Port patches from folia dev/optimisations

This commit is contained in:
Spottedleaf 2023-09-22 15:54:36 -07:00
parent d259503c92
commit 6af97e11b6
49 changed files with 5398 additions and 2254 deletions

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ Move collision logic to just the hasNewCollision call instead of getCubes + hasN
CHECK ME
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index a89915d288d517a1d3674d7d1eb28e8e3f3028a1..b998ec2a7350814ae7239d79a3dccf21b08670ce 100644
index a89915d288d517a1d3674d7d1eb28e8e3f3028a1..129079ccc05d153c912565a4f348c0332ba8453a 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -534,7 +534,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@ -142,28 +142,35 @@ index a89915d288d517a1d3674d7d1eb28e8e3f3028a1..b998ec2a7350814ae7239d79a3dccf21
this.internalTeleport(d3, d4, d5, f, f1, Collections.emptySet()); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround());
} else {
@@ -1477,6 +1524,26 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1477,6 +1524,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
}
+ // Paper start - optimise out extra getCubes
+ private boolean hasNewCollision(final ServerLevel world, final Entity entity, final AABB oldBox, final AABB newBox) {
+ final List<AABB> collisions = io.papermc.paper.util.CachedLists.getTempCollisionList();
+ try {
+ io.papermc.paper.util.CollisionUtil.getCollisions(world, entity, newBox, collisions, false, true,
+ true, false, null, null);
+ final List<AABB> collisionsBB = new java.util.ArrayList<>();
+ final List<VoxelShape> collisionsVoxel = new java.util.ArrayList<>();
+ io.papermc.paper.util.CollisionUtil.getCollisions(
+ world, entity, newBox, collisionsVoxel, collisionsBB,
+ io.papermc.paper.util.CollisionUtil.COLLISION_FLAG_COLLIDE_WITH_UNLOADED_CHUNKS | io.papermc.paper.util.CollisionUtil.COLLISION_FLAG_CHECK_BORDER,
+ null, null
+ );
+
+ for (int i = 0, len = collisions.size(); i < len; ++i) {
+ final AABB box = collisions.get(i);
+ if (!io.papermc.paper.util.CollisionUtil.voxelShapeIntersect(box, oldBox)) {
+ return true;
+ }
+ for (int i = 0, len = collisionsBB.size(); i < len; ++i) {
+ final AABB box = collisionsBB.get(i);
+ if (!io.papermc.paper.util.CollisionUtil.voxelShapeIntersect(box, oldBox)) {
+ return true;
+ }
+
+ return false;
+ } finally {
+ io.papermc.paper.util.CachedLists.returnTempCollisionList(collisions);
+ }
+
+ for (int i = 0, len = collisionsVoxel.size(); i < len; ++i) {
+ final VoxelShape voxel = collisionsVoxel.get(i);
+ if (!io.papermc.paper.util.CollisionUtil.voxelShapeIntersectNoEmpty(voxel, oldBox)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ // Paper end - optimise out extra getCubes
private boolean isPlayerCollidingWithAnythingNew(LevelReader world, AABB box, double newX, double newY, double newZ) {

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Forward CraftEntity in teleport command
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 2d303efd9ea5b5e96f1d2ec5a9c6f74c3785dd3e..da02b0280778d86c285579bf4e4eae62cb4798d3 100644
index f91cbf742ee12f29cdebbd0a1481f0ea6db8d50b..da8bd9746a3ddef673230c12370a34c8228aa0c7 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3447,6 +3447,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3494,6 +3494,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
public void restoreFrom(Entity original) {
@ -22,7 +22,7 @@ index 2d303efd9ea5b5e96f1d2ec5a9c6f74c3785dd3e..da02b0280778d86c285579bf4e4eae62
CompoundTag nbttagcompound = original.saveWithoutId(new CompoundTag());
nbttagcompound.remove("Dimension");
@@ -3533,10 +3540,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3580,10 +3587,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (worldserver.getTypeKey() == LevelStem.END) { // CraftBukkit
ServerLevel.makeObsidianPlatform(worldserver, this); // CraftBukkit
}

View File

@ -7,10 +7,10 @@ Makes the PlayerKickEvent fire on the main thread for
illegal characters or chat out-of-order errors.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index b998ec2a7350814ae7239d79a3dccf21b08670ce..9526dc19ef02f612db02a909392569f6d49a4a26 100644
index 129079ccc05d153c912565a4f348c0332ba8453a..c92316910a1744fcb0cecd981df713be2eb7e4d4 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2014,7 +2014,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2021,7 +2021,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
// CraftBukkit end
if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.message())) {
@ -20,7 +20,7 @@ index b998ec2a7350814ae7239d79a3dccf21b08670ce..9526dc19ef02f612db02a909392569f6
} else {
Optional<LastSeenMessages> optional = this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages());
@@ -2047,7 +2049,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2054,7 +2056,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleChatCommand(ServerboundChatCommandPacket packet) {
if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.command())) {
@ -30,7 +30,7 @@ index b998ec2a7350814ae7239d79a3dccf21b08670ce..9526dc19ef02f612db02a909392569f6
} else {
Optional<LastSeenMessages> optional = this.tryHandleChat(packet.command(), packet.timeStamp(), packet.lastSeenMessages());
@@ -2133,7 +2137,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2140,7 +2144,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
private Optional<LastSeenMessages> tryHandleChat(String message, Instant timestamp, LastSeenMessages.Update acknowledgment) {
if (!this.updateChatOrder(timestamp)) {
ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}'", this.player.getName().getString(), message);

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Freeze Tick Lock API
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index da02b0280778d86c285579bf4e4eae62cb4798d3..7c3c4b3e553b31000c3e90bc03f32730f1769c8b 100644
index da8bd9746a3ddef673230c12370a34c8228aa0c7..a1e795810e7e49acf4959b9c88bed1f9b91b030c 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -401,6 +401,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@ -25,7 +25,7 @@ index da02b0280778d86c285579bf4e4eae62cb4798d3..7c3c4b3e553b31000c3e90bc03f32730
this.setTicksFrozen(0);
this.level().levelEvent((Player) null, 1009, this.blockPosition, 1);
}
@@ -2392,6 +2393,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2400,6 +2401,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (fromNetherPortal) {
nbt.putBoolean("Paper.FromNetherPortal", true);
}
@ -35,7 +35,7 @@ index da02b0280778d86c285579bf4e4eae62cb4798d3..7c3c4b3e553b31000c3e90bc03f32730
// Paper end
return nbt;
} catch (Throwable throwable) {
@@ -2557,6 +2561,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2565,6 +2569,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (spawnReason == null) {
spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT;
}

View File

@ -7,7 +7,7 @@ Bring the vehicle move packet behavior in line with the
regular player move packet.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 9526dc19ef02f612db02a909392569f6d49a4a26..1d65adfddb19cfa343d0a16a0e0762d8bd6d947d 100644
index c92316910a1744fcb0cecd981df713be2eb7e4d4..5874502ce611e985462ee4c2946ae2f34c9b0442 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -463,6 +463,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Ensure entity passenger world matches ridden entity
Bad plugins doing this would cause some obvious problems...
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 7c3c4b3e553b31000c3e90bc03f32730f1769c8b..ca4547bc2d767a32d1fd22be858faf5e61cde9d0 100644
index a1e795810e7e49acf4959b9c88bed1f9b91b030c..b92cfb174d84c32d49786b3fd189b1602ff84ce1 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2761,7 +2761,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2808,7 +2808,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
public boolean startRiding(Entity entity, boolean force) {

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Guard against invalid entity positions
Anything not finite should be blocked and logged
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index ca4547bc2d767a32d1fd22be858faf5e61cde9d0..d62725d0084c50fb9f57a12bb28f76a5f83e947f 100644
index b92cfb174d84c32d49786b3fd189b1602ff84ce1..cb2b6ac12a93e5080e3d408e9797c011b5dccd09 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -4442,11 +4442,33 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -4489,11 +4489,33 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale);
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Prevent tile entity copies loading chunks
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 1d65adfddb19cfa343d0a16a0e0762d8bd6d947d..f4986bbb784febbeb5731ccf5392b4f153f5d466 100644
index 5874502ce611e985462ee4c2946ae2f34c9b0442..627d0f2bfc517aa36b87be26e82c5ca9e350bb75 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3181,7 +3181,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -3188,7 +3188,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound);
if (this.player.level().isLoaded(blockposition)) {

View File

@ -18,10 +18,10 @@ index c7894892afe97eb3cb453c37a2d9a23d811d70b8..2d06a8f85c5e29688aa0fd4726fd5767
if (dedicatedserverproperties.enableQuery) {
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index f4986bbb784febbeb5731ccf5392b4f153f5d466..e18d0c9d1ac520e574b81fe3a7545703006bed49 100644
index 627d0f2bfc517aa36b87be26e82c5ca9e350bb75..173bbf2fb19114df13e3c0209488e727cd58ab30 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2744,7 +2744,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2751,7 +2751,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.player = this.server.getPlayerList().respawn(this.player, false, RespawnReason.DEATH);
if (this.server.isHardcore()) {
this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Do not accept invalid client settings
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index e18d0c9d1ac520e574b81fe3a7545703006bed49..7bacbc914e05ae2780a32b93dec4522d494cd9db 100644
index 173bbf2fb19114df13e3c0209488e727cd58ab30..7cdbad2d295ade402536e0dc6f447996a49ea74b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3305,6 +3305,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -3312,6 +3312,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleClientInformation(ServerboundClientInformationPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Prevent entity loading causing async lookups
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index d62725d0084c50fb9f57a12bb28f76a5f83e947f..086134827363fa44644164e6660861213fdf1a9f 100644
index cb2b6ac12a93e5080e3d408e9797c011b5dccd09..bca885b3632c06c51d7d68f9f3ee1964a41bfdf3 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -763,6 +763,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {

View File

@ -2034,10 +2034,10 @@ index 6dcb9ee306326c3f3d0a23be4f12b56ffe78e3d7..4b1e55503e0ca813bc893a3a8258af8a
EntityCallbacks() {}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 57403c09141ece41a882c6574a593be391b34782..a1c564571f5ebda3419a96ab86b52b62cf72c8e2 100644
index 580aa991de9a617efd6e9e3b60923742c5e3346b..7e898e34490a47b1c505a67f8d0266384f4e37ff 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1475,4 +1475,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1853,4 +1853,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return ret;
}
// Paper end

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add various missing EntityDropItemEvent calls
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 086134827363fa44644164e6660861213fdf1a9f..fb363474f7b01a0a038f43edd9095f94a2b0b5a0 100644
index bca885b3632c06c51d7d68f9f3ee1964a41bfdf3..781b9c6d2f05535f67322ae6bdd1423c506ab7cd 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2652,6 +2652,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2660,6 +2660,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
entityitem.setDefaultPickUpDelay();

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Add some minimal debug information to chat packet errors
TODO: potentially add some kick leeway
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 7bacbc914e05ae2780a32b93dec4522d494cd9db..0d70654255777ae7c842feca343ccf7bd077c082 100644
index 7cdbad2d295ade402536e0dc6f447996a49ea74b..df8f49adf6b0d6c8334e1c8583e588278648022b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2141,7 +2141,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2148,7 +2148,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
private Optional<LastSeenMessages> tryHandleChat(String message, Instant timestamp, LastSeenMessages.Update acknowledgment) {
if (!this.updateChatOrder(timestamp)) {

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Fix Spigot Config not using commands.spam-exclusions
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0d70654255777ae7c842feca343ccf7bd077c082..bf8b5375147d186e2615d4f1e6658fe8ae43bcde 100644
index df8f49adf6b0d6c8334e1c8583e588278648022b..61840dbe2a8126fa247c745e6e27037a05f9b8e6 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2361,7 +2361,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2368,7 +2368,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
// Spigot end
// this.chatSpamTickCount += 20;

View File

@ -7,10 +7,10 @@ Subject: [PATCH] More Teleport API
public net.minecraft.server.network.ServerGamePacketListenerImpl internalTeleport(DDDFFLjava/util/Set;Z)V
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index bf8b5375147d186e2615d4f1e6658fe8ae43bcde..03dd7c827e537e0d2619632ad728ab4165032643 100644
index 61840dbe2a8126fa247c745e6e27037a05f9b8e6..c28a45b2093b805812258047d06e8064c267fb7b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1598,11 +1598,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1605,11 +1605,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return false; // CraftBukkit - Return event status
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add EntityPortalReadyEvent
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index fb363474f7b01a0a038f43edd9095f94a2b0b5a0..973b23d91de6e3bbdc3a9e9c69652d912bd47d06 100644
index 781b9c6d2f05535f67322ae6bdd1423c506ab7cd..073bd0e905b258be835b5063ddd5d8d6bb17d106 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3015,6 +3015,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3062,6 +3062,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (true && !this.isPassenger() && this.portalTime++ >= i) { // CraftBukkit
this.level().getProfiler().push("portal");
this.portalTime = i;
@ -22,7 +22,7 @@ index fb363474f7b01a0a038f43edd9095f94a2b0b5a0..973b23d91de6e3bbdc3a9e9c69652d91
this.setPortalCooldown();
// CraftBukkit start
if (this instanceof ServerPlayer) {
@@ -3022,6 +3029,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3069,6 +3076,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
} else {
this.changeDimension(worldserver1);
}

View File

@ -57,10 +57,10 @@ index f968dee743f58fe71935097701866800c0f382a1..73e2948210139e40e234b5e2107f9008
}
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 03dd7c827e537e0d2619632ad728ab4165032643..df6be8a358052c3305efdbf2704433b74ffc3a0f 100644
index c28a45b2093b805812258047d06e8064c267fb7b..ff65e2cc10a3197f09086ed5c4baa44305af158e 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1744,8 +1744,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1751,8 +1751,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return;
}
// Paper end - Don't allow digging in unloaded chunks

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Warn on plugins accessing faraway chunks
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index a1c564571f5ebda3419a96ab86b52b62cf72c8e2..ed6e1bb540138e7c83df51cfd5c52dcc87fca076 100644
index 7e898e34490a47b1c505a67f8d0266384f4e37ff..1531809d6bb80ae1fd50a08a541578f44d624fd8 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -440,7 +440,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -808,7 +808,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}
private static boolean isInWorldBoundsHorizontal(BlockPos pos) {

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Fix EntityCombustEvent cancellation cant fully prevent
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 973b23d91de6e3bbdc3a9e9c69652d912bd47d06..5c82e2ceeb3c0a3bec441d988e730fff0e934f42 100644
index 073bd0e905b258be835b5063ddd5d8d6bb17d106..dd0eb9ee56fb41e4488b76a51f9daf6875155c31 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3294,6 +3294,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3341,6 +3341,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
pluginManager.callEvent(entityCombustEvent);
if (!entityCombustEvent.isCancelled()) {
this.setSecondsOnFire(entityCombustEvent.getDuration(), false);

View File

@ -50,10 +50,10 @@ index 4b2cd6d34ea4081cad86041f57ccda41807d4279..807cff3fb51269b97d9aecbcc4706f0a
if (entityhuman instanceof ServerPlayer) {
CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer) entityhuman, this, entityvillager);
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
index 258824816894d8fc0d8f1ee80489f66658a9ae80..a7e646071e739da363d75d5c35f48e473e405c6b 100644
index 9f892de55ab03367daed4c30cc44c9dd8adc29ed..b3293a722fb5c5262a777402140c764c03367800 100644
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
@@ -243,4 +243,11 @@ public interface EntityGetter {
@@ -280,4 +280,11 @@ public interface EntityGetter {
return null;
}

View File

@ -82,10 +82,10 @@ index d088479d160dbd2fc90b48a30553be141db8eef2..15add3f4dfd718ec09bb1db4f2222346
public static class DataItem<T> {
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index df6be8a358052c3305efdbf2704433b74ffc3a0f..aee557c408a914d8213e2e6a92838c507b8f830c 100644
index ff65e2cc10a3197f09086ed5c4baa44305af158e..964e2efa84f198a65d2f221b7ba3c155f855de32 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2641,7 +2641,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2648,7 +2648,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
// Entity in bucket - SPIGOT-4048 and SPIGOT-6859a
if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) {

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Improve inlining for some hot BlockBehavior and FluidState
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
index 04b27d3797057b80e71d2d32c9e31c3fba39c86b..525632059dc7cf911ce485e925a3c8d6ba5a4f86 100644
index fc28bca0d31b01287f38405f795da577c6c89105..e6a4a5898ffdcb2aa2bc01371a6d7dbc06d610ce 100644
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -963,15 +963,15 @@ public abstract class BlockBehaviour implements FeatureElement {
@@ -1011,15 +1011,15 @@ public abstract class BlockBehaviour implements FeatureElement {
return this.shapeExceedsCube; // Paper - moved into shape cache init
}
@ -28,7 +28,7 @@ index 04b27d3797057b80e71d2d32c9e31c3fba39c86b..525632059dc7cf911ce485e925a3c8d6
return this.isAir;
}
@@ -1055,7 +1055,7 @@ public abstract class BlockBehaviour implements FeatureElement {
@@ -1103,7 +1103,7 @@ public abstract class BlockBehaviour implements FeatureElement {
}
}
@ -37,7 +37,7 @@ index 04b27d3797057b80e71d2d32c9e31c3fba39c86b..525632059dc7cf911ce485e925a3c8d6
return this.canOcclude;
}
@@ -1255,11 +1255,11 @@ public abstract class BlockBehaviour implements FeatureElement {
@@ -1303,11 +1303,11 @@ public abstract class BlockBehaviour implements FeatureElement {
return this.getBlock() == block;
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Improve logging and errors
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index aee557c408a914d8213e2e6a92838c507b8f830c..4a3a7a57100dd2c69ffd3cfb1c49e811801e1409 100644
index 964e2efa84f198a65d2f221b7ba3c155f855de32..f44faa3b544c12145b7251446809013ae3283a93 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3378,7 +3378,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -3385,7 +3385,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator));
} catch (ProfilePublicKey.ValidationException profilepublickey_b) {

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Improve PortalEvents
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 5c82e2ceeb3c0a3bec441d988e730fff0e934f42..d173703fe775eb064f8e1889403297931f1cf371 100644
index dd0eb9ee56fb41e4488b76a51f9daf6875155c31..e68b8d53cacf179050dbc9cbfd815be7159dc8bc 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3677,7 +3677,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3724,7 +3724,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
Location enter = bukkitEntity.getLocation();
Location exit = CraftLocation.toBukkit(exitPosition, exitWorldServer.getWorld());

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Add config option for spider worldborder climbing
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index d173703fe775eb064f8e1889403297931f1cf371..52778a4fda0fa1850a95c4944b35da1527efabfc 100644
index e68b8d53cacf179050dbc9cbfd815be7159dc8bc..ba9b6bf4ff7c23ca599e09ff2fcbf9ab5d270f5d 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -402,6 +402,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@ -16,14 +16,14 @@ index d173703fe775eb064f8e1889403297931f1cf371..52778a4fda0fa1850a95c4944b35da15
public void setOrigin(@javax.annotation.Nonnull Location location) {
this.origin = location.toVector();
@@ -1436,7 +1437,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
io.papermc.paper.util.CollisionUtil.getCollisions(world, this, collisionBox, potentialCollisions, false, this.level.paperConfig().chunks.preventMovingIntoUnloadedChunks,
false, false, null, null);
@@ -1443,7 +1444,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
null, null
);
- if (io.papermc.paper.util.CollisionUtil.isCollidingWithBorderEdge(world.getWorldBorder(), collisionBox)) {
+ if (collidingWithWorldBorder = io.papermc.paper.util.CollisionUtil.isCollidingWithBorderEdge(world.getWorldBorder(), collisionBox)) { // Paper - this line *is* correct, ignore the IDE warning about assignments being used as a condition
io.papermc.paper.util.CollisionUtil.addBoxesToIfIntersects(world.getWorldBorder().getCollisionShape(), collisionBox, potentialCollisions);
}
- if (io.papermc.paper.util.CollisionUtil.isCollidingWithBorderEdge(world.getWorldBorder(), collisionBox)) {
+ if (collidingWithWorldBorder = io.papermc.paper.util.CollisionUtil.isCollidingWithBorderEdge(world.getWorldBorder(), collisionBox)) { // Paper - this line *is* correct, ignore the IDE warning about assignments being used as a condition
potentialCollisionsVoxel.add(world.getWorldBorder().getCollisionShape());
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
index 9e5d68fe86d17118df3d6a1c36b296f32b4d7fc1..71b5a9c97a13f703073c0122742ff9e8a0e49df2 100644

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add missing SpigotConfig logCommands check
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 4a3a7a57100dd2c69ffd3cfb1c49e811801e1409..be6245a1b01cb76641d31f33e2edeb7b815fae6a 100644
index f44faa3b544c12145b7251446809013ae3283a93..fca275842215dc0b4e413129afb45cc3cd30156a 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2105,7 +2105,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2112,7 +2112,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
private void performChatCommand(ServerboundChatCommandPacket packet, LastSeenMessages lastSeenMessages) {
// CraftBukkit start
String command = "/" + packet.command();

View File

@ -6,7 +6,7 @@ Subject: [PATCH] Expose pre-collision moving velocity to
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 52778a4fda0fa1850a95c4944b35da1527efabfc..01bbce773adc1a4c1720a43250de825d83a89da4 100644
index ba9b6bf4ff7c23ca599e09ff2fcbf9ab5d270f5d..7fae13799800478f6244eaaeed59956494b3323b 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1123,7 +1123,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Use single player info update packet on join
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index be6245a1b01cb76641d31f33e2edeb7b815fae6a..7abada5b8b6b92f998154b6cb9851c4d0a19e717 100644
index fca275842215dc0b4e413129afb45cc3cd30156a..dafd15487831fc2269d23e04a001e3c4c33bb9ba 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3408,7 +3408,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -3415,7 +3415,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID());
this.chatMessageChain.append((executor) -> {
this.player.setChatSession(session);

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Update the flag when a captured block state is outdated
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index ed6e1bb540138e7c83df51cfd5c52dcc87fca076..49417e67ff27b77955e73908886d0a0ce3a44644 100644
index 1531809d6bb80ae1fd50a08a541578f44d624fd8..d5308b66d7fd9b230862503acfa84dac2ddc2582 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -550,6 +550,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -918,6 +918,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags);
this.capturedBlockStates.put(pos.immutable(), blockstate);
}

View File

@ -68,10 +68,70 @@ index 5bdad1866386908b9fef74d15862eb107fabe68f..370a25d2deb54f10a35ee24d9e7e92fb
}
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b13898f50 100644
index f98367830e87d5f1428448931f756d9277699563..1d9b23c6e458caddc2c738164e6c079cd85d3ce9 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -193,6 +193,202 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -151,6 +151,43 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
+ // Paper start - optimize hoppers
+ private static final int HOPPER_EMPTY = 0;
+ private static final int HOPPER_HAS_ITEMS = 1;
+ private static final int HOPPER_IS_FULL = 2;
+
+ private static int getFullState(final HopperBlockEntity tileEntity) {
+ tileEntity.unpackLootTable(null);
+
+ final List<ItemStack> hopperItems = tileEntity.getItems();
+
+ boolean empty = true;
+ boolean full = true;
+
+ for (int i = 0, len = hopperItems.size(); i < len; ++i) {
+ final ItemStack stack = hopperItems.get(i);
+ if (stack.isEmpty()) {
+ full = false;
+ continue;
+ }
+
+ if (!full) {
+ // can't be full
+ return HOPPER_HAS_ITEMS;
+ }
+
+ empty = false;
+
+ if (stack.getCount() != stack.getMaxStackSize()) {
+ // can't be full or empty
+ return HOPPER_HAS_ITEMS;
+ }
+ }
+
+ return empty ? HOPPER_EMPTY : (full ? HOPPER_IS_FULL : HOPPER_HAS_ITEMS);
+ }
+ // Paper end - optimize hoppers
+
private static boolean tryMoveItems(Level world, BlockPos pos, BlockState state, HopperBlockEntity blockEntity, BooleanSupplier booleansupplier) {
if (world.isClientSide) {
return false;
@@ -158,11 +195,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (!blockEntity.isOnCooldown() && (Boolean) state.getValue(HopperBlock.ENABLED)) {
boolean flag = false;
- if (!blockEntity.isEmpty()) {
+ int fullState = getFullState(blockEntity); // Paper - optimize hoppers
+
+ if (fullState != HOPPER_EMPTY) { // Paper - optimize hoppers
flag = HopperBlockEntity.ejectItems(world, pos, state, (Container) blockEntity, blockEntity); // CraftBukkit
}
- if (!blockEntity.inventoryFull()) {
+ if (fullState != HOPPER_IS_FULL || flag) { // Paper - optimize hoppers
flag |= booleansupplier.getAsBoolean();
}
@@ -193,6 +232,202 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
return false;
}
@ -274,7 +334,7 @@ index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b
private static boolean ejectItems(Level world, BlockPos blockposition, BlockState iblockdata, Container iinventory, HopperBlockEntity hopper) { // CraftBukkit
Container iinventory1 = HopperBlockEntity.getAttachedContainer(world, blockposition, iblockdata);
@@ -204,46 +400,49 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -204,46 +439,49 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (HopperBlockEntity.isFullContainer(iinventory1, enumdirection)) {
return false;
} else {
@ -360,7 +420,7 @@ index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b
}
}
}
@@ -253,17 +452,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -253,17 +491,29 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
private static boolean isFullContainer(Container inventory, Direction direction) {
@ -369,7 +429,25 @@ index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b
-
- return itemstack.getCount() >= itemstack.getMaxStackSize();
- });
+ return allMatch(inventory, direction, STACK_SIZE_TEST); // Paper - no streams
+ // Paper start - optimize hoppers
+ if (inventory instanceof WorldlyContainer worldlyContainer) {
+ for (final int slot : worldlyContainer.getSlotsForFace(direction)) {
+ final ItemStack stack = inventory.getItem(slot);
+ if (stack.getCount() < stack.getMaxStackSize()) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ for (int slot = 0, max = inventory.getContainerSize(); slot < max; ++slot) {
+ final ItemStack stack = inventory.getItem(slot);
+ if (stack.getCount() < stack.getMaxStackSize()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // Paper end - optimize hoppers
}
private static boolean isEmptyContainer(Container inv, Direction facing) {
@ -380,26 +458,44 @@ index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b
}
public static boolean suckInItems(Level world, Hopper hopper) {
@@ -272,8 +465,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -272,9 +522,33 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (iinventory != null) {
Direction enumdirection = Direction.DOWN;
- return HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) ? false : HopperBlockEntity.getSlots(iinventory, enumdirection).anyMatch((i) -> {
- return HopperBlockEntity.a(hopper, iinventory, i, enumdirection, world); // Spigot
- });
+ // Paper start - optimize hoppers and remove streams
+ skipPullModeEventFire = skipHopperEvents;
+ return !HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) && anyMatch(iinventory, enumdirection, (item, i) -> {
+ // Logic copied from below to avoid extra getItem calls
+ if (!item.isEmpty() && canTakeItemFromContainer(hopper, iinventory, item, i, enumdirection)) {
+ return hopperPull(world, hopper, iinventory, item, i);
+ } else {
+ return false;
+ // merge container isEmpty check and move logic into one loop
+ if (iinventory instanceof WorldlyContainer worldlyContainer) {
+ for (final int slot : worldlyContainer.getSlotsForFace(enumdirection)) {
+ ItemStack item = worldlyContainer.getItem(slot);
+ if (item.isEmpty() || !canTakeItemFromContainer(hopper, iinventory, item, slot, enumdirection)) {
+ continue;
+ }
+ if (hopperPull(world, hopper, iinventory, item, slot)) {
+ return true;
+ }
+ }
+ // Paper end
});
+ return false;
+ } else {
+ for (int slot = 0, max = iinventory.getContainerSize(); slot < max; ++slot) {
+ ItemStack item = iinventory.getItem(slot);
+ if (item.isEmpty() || !canTakeItemFromContainer(hopper, iinventory, item, slot, enumdirection)) {
+ continue;
+ }
+ if (hopperPull(world, hopper, iinventory, item, slot)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // Paper end
} else {
Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator();
@@ -292,48 +493,52 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -292,48 +566,52 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
}
@ -491,16 +587,23 @@ index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b
}
return false;
@@ -342,7 +547,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -342,12 +620,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
public static boolean addItem(Container inventory, ItemEntity itemEntity) {
boolean flag = false;
// CraftBukkit start
- InventoryPickupItemEvent event = new InventoryPickupItemEvent(inventory.getOwner().getInventory(), (org.bukkit.entity.Item) itemEntity.getBukkitEntity());
+ if (InventoryPickupItemEvent.getHandlerList().getRegisteredListeners().length > 0) { // Paper - optimize hoppers
+ InventoryPickupItemEvent event = new InventoryPickupItemEvent(getInventory(inventory), (org.bukkit.entity.Item) itemEntity.getBukkitEntity()); // Paper - use getInventory() to avoid snapshot creation
itemEntity.level().getCraftServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
@@ -443,7 +648,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
// CraftBukkit end
+ } // Paper - optimize hoppers
ItemStack itemstack = itemEntity.getItem().copy();
ItemStack itemstack1 = HopperBlockEntity.addItem((Container) null, inventory, itemstack, (Direction) null);
@@ -443,7 +723,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
stack = stack.split(to.getMaxStackSize());
}
// Spigot end
@ -510,7 +613,7 @@ index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b
stack = leftover; // Paper
flag = true;
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
@@ -517,19 +724,47 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -517,19 +799,47 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
// CraftBukkit end
}
@ -562,16 +665,18 @@ index f98367830e87d5f1428448931f756d9277699563..e2e845a01e43bc01aba7a148d2b2d55b
Object object = null;
BlockPos blockposition = BlockPos.containing(x, y, z);
if ( !world.spigotConfig.hopperCanLoadChunks && !world.hasChunkAt( blockposition ) ) return null; // Spigot
@@ -549,7 +784,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -549,8 +859,8 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
}
- if (object == null) {
+ if (object == null && (!optimizeEntities || !world.paperConfig().hopper.ignoreOccludingBlocks || !org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(block).isOccluding())) { // Paper
List<Entity> list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR);
- List<Entity> list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR);
+ if (object == null && (!optimizeEntities || !world.paperConfig().hopper.ignoreOccludingBlocks || !iblockdata.getBukkitMaterial().isOccluding())) { // Paper
+ List<Entity> list = world.getEntitiesOfClass((Class)Container.class, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR); // Paper - optimize hoppers, use getEntitiesOfClass
if (!list.isEmpty()) {
@@ -561,7 +796,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
object = (Container) list.get(world.random.nextInt(list.size()));
@@ -561,7 +871,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
private static boolean canMergeItems(ItemStack first, ItemStack second) {

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Treat sequence violations like they should be
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 7abada5b8b6b92f998154b6cb9851c4d0a19e717..af6a7c14b1028745d0bb51ee90d819cc9e75395d 100644
index dafd15487831fc2269d23e04a001e3c4c33bb9ba..3ea992964ac73b2348464e923547c7a762f1f65a 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2004,6 +2004,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2011,6 +2011,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
public void ackBlockChangesUpTo(int sequence) {
if (sequence < 0) {

View File

@ -24,7 +24,7 @@ index 40ac5cf19934207f06755fbea02d4626d7aa0511..32e3f347e2e025e2675e9410116386e4
UPDATE_GAME_MODE((serialized, buf) -> {
serialized.gameMode = GameType.byId(buf.readVarInt());
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index af6a7c14b1028745d0bb51ee90d819cc9e75395d..d3591313fab215a2d29480e3427eadf2c30f9b63 100644
index 3ea992964ac73b2348464e923547c7a762f1f65a..396159bc2ad8a81f67135bd10d64374a0dc68ceb 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -284,6 +284,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@ -49,7 +49,7 @@ index af6a7c14b1028745d0bb51ee90d819cc9e75395d..d3591313fab215a2d29480e3427eadf2
}
public void resetPosition() {
@@ -3406,6 +3414,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -3413,6 +3421,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
private void resetPlayerChatState(RemoteChatSession session) {
this.chatSession = session;

View File

@ -16,10 +16,10 @@ sections with a ZeroBitStorage data to to take ~20% of the process,
now it takes <1%.
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
index f150a16fbf888455301d8b9043f0b45fb1fa1d84..fd4c4122e3811c8f5d8c02f8faaf3579bcb8ad79 100644
index 4158a699d775e1a69974b1a638714ffcadafaa46..93f0f55d986c2ae838f1cae10dc80ab31a7eaec4 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -229,6 +229,7 @@ public class LevelChunkSection {
@@ -141,6 +141,7 @@ public class LevelChunkSection {
this.nonEmptyBlockCount = 0;
this.tickingBlockCount = 0;
this.tickingFluidCount = 0;
@ -27,11 +27,11 @@ index f150a16fbf888455301d8b9043f0b45fb1fa1d84..fd4c4122e3811c8f5d8c02f8faaf3579
this.states.forEachLocation((BlockState iblockdata, int i) -> {
FluidState fluid = iblockdata.getFluidState();
@@ -248,6 +249,7 @@ public class LevelChunkSection {
}
@@ -166,6 +167,7 @@ public class LevelChunkSection {
// Paper end - optimise collisions
});
+ } // Paper - do not run forEachLocation on clearly empty sections
// Paper end
this.initBlockCollisionData(); // Paper
}

View File

@ -14,7 +14,7 @@ clearing the owner.
Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 01bbce773adc1a4c1720a43250de825d83a89da4..768e243c44ed3c95339efa46827a81f0a679250d 100644
index 7fae13799800478f6244eaaeed59956494b3323b..2ec75c46f53331442d79ef30b7f8acb317f0143b 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -381,6 +381,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {

View File

@ -41,10 +41,10 @@ index 08464c7f114a04169c9ddeceef936749952770e6..62fc1b110ec319bb91aa0639b18aa354
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 49417e67ff27b77955e73908886d0a0ce3a44644..aa21c3b9ac5101d0c2150baf2c259ed247e94349 100644
index d5308b66d7fd9b230862503acfa84dac2ddc2582..8f08f39a6ebd16e0cadb9a405035d995caf9f333 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -664,17 +664,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1032,17 +1032,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// CraftBukkit start
iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam
CraftWorld world = ((ServerLevel) this).getWorld();

View File

@ -34,10 +34,10 @@ index 482e6b217c073ceff30c238c3a8cd8ea526bb07c..034960c1d321e159b3881a900f823ba5
return enuminteractionresult;
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index d3591313fab215a2d29480e3427eadf2c30f9b63..41b8cab749d3fd8b6517297ff5d511204dccdf20 100644
index 396159bc2ad8a81f67135bd10d64374a0dc68ceb..689963e8b458b2fe171a1e26b9e659d0d73423e1 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1916,6 +1916,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1923,6 +1923,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
if (cancelled) {

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Don't load chunks for supporting block checks
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 768e243c44ed3c95339efa46827a81f0a679250d..e07be1692ecee46e0eb9188e2cf8ee1c16c6cc1c 100644
index 2ec75c46f53331442d79ef30b7f8acb317f0143b..ac7f1f317782a6c6ad41614fbe6c25498da63010 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1323,7 +1323,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Implement PlayerFailMoveEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 41b8cab749d3fd8b6517297ff5d511204dccdf20..2cb2d0e89687be15b54a801c077f7755040f7b0d 100644
index 689963e8b458b2fe171a1e26b9e659d0d73423e1..75859a5171892867b528ceb85b44c34eac4d902e 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1291,8 +1291,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@ -101,4 +101,4 @@ index 41b8cab749d3fd8b6517297ff5d511204dccdf20..2cb2d0e89687be15b54a801c077f7755
+ // Paper end
// Paper start - optimise out extra getCubes
private boolean hasNewCollision(final ServerLevel world, final Entity entity, final AABB oldBox, final AABB newBox) {
final List<AABB> collisions = io.papermc.paper.util.CachedLists.getTempCollisionList();
final List<AABB> collisionsBB = new java.util.ArrayList<>();

View File

@ -1158,7 +1158,7 @@ index 4cbb35cac2736c80cba2a72649c485a3ea8e920b..723a87701a44e379c80e6def91c5340e
this.players.remove(entityplayer);
this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index e07be1692ecee46e0eb9188e2cf8ee1c16c6cc1c..41136785bc2beb3cb2ae09c85d55eac6c94eda42 100644
index ac7f1f317782a6c6ad41614fbe6c25498da63010..426023af3cbed9c17048e669c87a1c66bda4ad1b 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -245,11 +245,23 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@ -1186,7 +1186,7 @@ index e07be1692ecee46e0eb9188e2cf8ee1c16c6cc1c..41136785bc2beb3cb2ae09c85d55eac6
@Override
public CommandSender getBukkitSender(CommandSourceStack wrapper) {
return this.getBukkitEntity();
@@ -4638,6 +4650,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -4685,6 +4697,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return;
}
// Paper end - rewrite chunk system
@ -1194,7 +1194,7 @@ index e07be1692ecee46e0eb9188e2cf8ee1c16c6cc1c..41136785bc2beb3cb2ae09c85d55eac6
if (this.removalReason == null) {
this.removalReason = reason;
}
@@ -4648,12 +4661,28 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -4695,12 +4708,28 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (reason != RemovalReason.UNLOADED_TO_CHUNK) this.getPassengers().forEach(Entity::stopRiding); // Paper - chunk system - don't adjust passenger state when unloading, it's just not safe (and messes with our logic in entity chunk unload)
this.levelCallback.onRemove(reason);

View File

@ -29,10 +29,10 @@ index 7bb47643e748f57a51c613d0a2ee8d05e1fe1798..16f087adbf94b8fd6726ffd300b103dd
}
entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index aa21c3b9ac5101d0c2150baf2c259ed247e94349..884871cf33a3073549109f5c4ba738bb34a21a6e 100644
index 8f08f39a6ebd16e0cadb9a405035d995caf9f333..1746159398a2bee2a86d82d5be035d68c1c3261a 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1487,4 +1487,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1865,4 +1865,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return null;
}
// Paper end - optimize redstone (Alternate Current)

View File

@ -11,7 +11,7 @@ This patch prevents server from sending namespaced commands when player
requests tab-complete only commands.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 2cb2d0e89687be15b54a801c077f7755040f7b0d..2dddfea4bb9f1d613d7497dd84d59ecd99f09b7a 100644
index 75859a5171892867b528ceb85b44c34eac4d902e..0a1d77ff0e29cee7d85eab02fb6f1e0578f32493 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -805,6 +805,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl

View File

@ -39,7 +39,7 @@ index 5cf7b0d0331a8f10aea6dd607193795054a299dd..4b4a6b081ffedc7f637fa1e1726391d8
BeehiveBlockEntity tileentitybeehive = (BeehiveBlockEntity) blockEntity;
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index 9522e646529f3d849471931b4b3c0d133e7fcfc5..fdd9c61b7248e92dbcbec91cd6fe4c6310bba237 100644
index 6c6532e1e73154ab5e6cb18aea44d64870dbbf4f..d4cbff18adb62073a1dceb189043789620af6877 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -416,10 +416,18 @@ public class Block extends BlockBehaviour implements ItemLike {

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Expand Pose API
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 41136785bc2beb3cb2ae09c85d55eac6c94eda42..aba3833e56bcce8e7b60382bc05b012e7c9eaed3 100644
index 426023af3cbed9c17048e669c87a1c66bda4ad1b..f20ae9153b7098980ce6c0e75fcbbb4da652661b 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -416,6 +416,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerPickItemEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 2dddfea4bb9f1d613d7497dd84d59ecd99f09b7a..264307bf5e1352f1ea82f1ec04c9645047b4ff9b 100644
index 0a1d77ff0e29cee7d85eab02fb6f1e0578f32493..72db2078e73c4384ee163c479ca56d6e50fc2f40 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -942,7 +942,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl

View File

@ -47,10 +47,10 @@ index 8e9469fec42f7b6a132cf173f6f5a95777a29b3b..b319021b22c5dceba6199ed27814b2dc
this.reassessWeaponGoal();
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 884871cf33a3073549109f5c4ba738bb34a21a6e..670d648baa76cf9c3367d8ce4b65d7dbd52801be 100644
index 1746159398a2bee2a86d82d5be035d68c1c3261a..ce422c31385d9518e798c7a3456fad747b09ea61 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1489,7 +1489,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1867,7 +1867,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// Paper end - optimize redstone (Alternate Current)
// Paper start - notify observers even if grow failed
public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final CraftBlockState craftBlockState) {

View File

@ -0,0 +1,496 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 12 Sep 2023 06:50:16 -0700
Subject: [PATCH] Actually optimise explosions
The vast majority of blocks an explosion of power ~4 tries
to destroy are duplicates. The core of the block destroying
part of this patch is to cache the block state, resistance, and
whether it should explode - as those will not change.
The other part of this patch is to optimise the visibility
percentage calculation. The new visibility calculation takes
advantage of the block caching already done by the explosion logic.
It continues to update the cache as the visibility calculation
uses many rays which can overlap significantly.
Effectively, the patch uses a lot of caching to eliminate
redundant operations.
Performance benchmarking explosions is challenging, as it varies
depending on the power, the number of nearby entities, and the
nearby terrain. This means that no benchmark can cover all the cases.
I decided to test a giant block of TNT, as that's where the optimisations
would be needed the most.
I tested using a 50x10x50 block of TNT above ground
and determined the following:
Vanilla time per explosion: 2.27ms
Lithium time per explosion: 1.07ms
This patch time per explosion: 0.45ms
The results indicate that this logic is 5 times faster than Vanilla
and 2.3 times faster than Lithium.
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index c1eafcc5b0e6486a6bffc497091e1d48b6b31a7e..45243249a561440512ef2a620c60b02e159c80e2 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -97,6 +97,271 @@ public class Explosion {
this.damageCalculator = behavior == null ? this.makeDamageCalculator(entity) : behavior;
}
+ // Paper start - optimise collisions
+ private static final double[] CACHED_RAYS;
+ static {
+ final it.unimi.dsi.fastutil.doubles.DoubleArrayList rayCoords = new it.unimi.dsi.fastutil.doubles.DoubleArrayList();
+
+ for (int x = 0; x <= 15; ++x) {
+ for (int y = 0; y <= 15; ++y) {
+ for (int z = 0; z <= 15; ++z) {
+ if ((x == 0 || x == 15) || (y == 0 || y == 15) || (z == 0 || z == 15)) {
+ double xDir = (double)((float)x / 15.0F * 2.0F - 1.0F);
+ double yDir = (double)((float)y / 15.0F * 2.0F - 1.0F);
+ double zDir = (double)((float)z / 15.0F * 2.0F - 1.0F);
+
+ double mag = Math.sqrt(
+ xDir * xDir + yDir * yDir + zDir * zDir
+ );
+
+ rayCoords.add((xDir / mag) * (double)0.3F);
+ rayCoords.add((yDir / mag) * (double)0.3F);
+ rayCoords.add((zDir / mag) * (double)0.3F);
+ }
+ }
+ }
+ }
+
+ CACHED_RAYS = rayCoords.toDoubleArray();
+ }
+
+ private static final int CHUNK_CACHE_SHIFT = 2;
+ private static final int CHUNK_CACHE_MASK = (1 << CHUNK_CACHE_SHIFT) - 1;
+ private static final int CHUNK_CACHE_WIDTH = 1 << CHUNK_CACHE_SHIFT;
+
+ private static final int BLOCK_EXPLOSION_CACHE_SHIFT = 3;
+ private static final int BLOCK_EXPLOSION_CACHE_MASK = (1 << BLOCK_EXPLOSION_CACHE_SHIFT) - 1;
+ private static final int BLOCK_EXPLOSION_CACHE_WIDTH = 1 << BLOCK_EXPLOSION_CACHE_SHIFT;
+
+ // resistance = (res + 0.3F) * 0.3F;
+ // so for resistance = 0, we need res = -0.3F
+ private static final Float ZERO_RESISTANCE = Float.valueOf(-0.3f);
+ private it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<ExplosionBlockCache> blockCache = null;
+
+ public static final class ExplosionBlockCache {
+
+ public final long key;
+ public final BlockPos immutablePos;
+ public final BlockState blockState;
+ public final FluidState fluidState;
+ public final float resistance;
+ public final boolean outOfWorld;
+ public Boolean shouldExplode; // null -> not called yet
+ public net.minecraft.world.phys.shapes.VoxelShape cachedCollisionShape;
+
+ public ExplosionBlockCache(long key, BlockPos immutablePos, BlockState blockState, FluidState fluidState, float resistance,
+ boolean outOfWorld) {
+ this.key = key;
+ this.immutablePos = immutablePos;
+ this.blockState = blockState;
+ this.fluidState = fluidState;
+ this.resistance = resistance;
+ this.outOfWorld = outOfWorld;
+ }
+ }
+
+ private long[] chunkPosCache = null;
+ private net.minecraft.world.level.chunk.LevelChunk[] chunkCache = null;
+
+ private ExplosionBlockCache getOrCacheExplosionBlock(final int x, final int y, final int z,
+ final long key, final boolean calculateResistance) {
+ ExplosionBlockCache ret = this.blockCache.get(key);
+ if (ret != null) {
+ return ret;
+ }
+
+ BlockPos pos = new BlockPos(x, y, z);
+
+ if (!this.level.isInWorldBounds(pos)) {
+ ret = new ExplosionBlockCache(key, pos, null, null, 0.0f, true);
+ } else {
+ net.minecraft.world.level.chunk.LevelChunk chunk;
+ long chunkKey = io.papermc.paper.util.CoordinateUtils.getChunkKey(x >> 4, z >> 4);
+ int chunkCacheKey = ((x >> 4) & CHUNK_CACHE_MASK) | (((z >> 4) << CHUNK_CACHE_SHIFT) & (CHUNK_CACHE_MASK << CHUNK_CACHE_SHIFT));
+ if (this.chunkPosCache[chunkCacheKey] == chunkKey) {
+ chunk = this.chunkCache[chunkCacheKey];
+ } else {
+ this.chunkPosCache[chunkCacheKey] = chunkKey;
+ this.chunkCache[chunkCacheKey] = chunk = this.level.getChunk(x >> 4, z >> 4);
+ }
+
+ BlockState blockState = chunk.getBlockStateFinal(x, y, z);
+ FluidState fluidState = blockState.getFluidState();
+
+ Optional<Float> resistance = !calculateResistance ? Optional.empty() : this.damageCalculator.getBlockExplosionResistance((Explosion)(Object)this, this.level, pos, blockState, fluidState);
+
+ ret = new ExplosionBlockCache(
+ key, pos, blockState, fluidState,
+ (resistance.orElse(ZERO_RESISTANCE).floatValue() + 0.3f) * 0.3f,
+ false
+ );
+ }
+
+ this.blockCache.put(key, ret);
+
+ return ret;
+ }
+
+ private boolean clipsAnything(final Vec3 from, final Vec3 to,
+ final io.papermc.paper.util.CollisionUtil.LazyEntityCollisionContext context,
+ final ExplosionBlockCache[] blockCache,
+ final BlockPos.MutableBlockPos currPos) {
+ // assume that context.delegated = false
+ final double adjX = io.papermc.paper.util.CollisionUtil.COLLISION_EPSILON * (from.x - to.x);
+ final double adjY = io.papermc.paper.util.CollisionUtil.COLLISION_EPSILON * (from.y - to.y);
+ final double adjZ = io.papermc.paper.util.CollisionUtil.COLLISION_EPSILON * (from.z - to.z);
+
+ if (adjX == 0.0 && adjY == 0.0 && adjZ == 0.0) {
+ return false;
+ }
+
+ final double toXAdj = to.x - adjX;
+ final double toYAdj = to.y - adjY;
+ final double toZAdj = to.z - adjZ;
+ final double fromXAdj = from.x + adjX;
+ final double fromYAdj = from.y + adjY;
+ final double fromZAdj = from.z + adjZ;
+
+ int currX = Mth.floor(fromXAdj);
+ int currY = Mth.floor(fromYAdj);
+ int currZ = Mth.floor(fromZAdj);
+
+ final double diffX = toXAdj - fromXAdj;
+ final double diffY = toYAdj - fromYAdj;
+ final double diffZ = toZAdj - fromZAdj;
+
+ final double dxDouble = Math.signum(diffX);
+ final double dyDouble = Math.signum(diffY);
+ final double dzDouble = Math.signum(diffZ);
+
+ final int dx = (int)dxDouble;
+ final int dy = (int)dyDouble;
+ final int dz = (int)dzDouble;
+
+ final double normalizedDiffX = diffX == 0.0 ? Double.MAX_VALUE : dxDouble / diffX;
+ final double normalizedDiffY = diffY == 0.0 ? Double.MAX_VALUE : dyDouble / diffY;
+ final double normalizedDiffZ = diffZ == 0.0 ? Double.MAX_VALUE : dzDouble / diffZ;
+
+ double normalizedCurrX = normalizedDiffX * (diffX > 0.0 ? (1.0 - Mth.frac(fromXAdj)) : Mth.frac(fromXAdj));
+ double normalizedCurrY = normalizedDiffY * (diffY > 0.0 ? (1.0 - Mth.frac(fromYAdj)) : Mth.frac(fromYAdj));
+ double normalizedCurrZ = normalizedDiffZ * (diffZ > 0.0 ? (1.0 - Mth.frac(fromZAdj)) : Mth.frac(fromZAdj));
+
+ for (;;) {
+ currPos.set(currX, currY, currZ);
+
+ // ClipContext.Block.COLLIDER -> BlockBehaviour.BlockStateBase::getCollisionShape
+ // ClipContext.Fluid.NONE -> ignore fluids
+
+ // read block from cache
+ final long key = BlockPos.asLong(currX, currY, currZ);
+
+ final int cacheKey =
+ (currX & BLOCK_EXPLOSION_CACHE_MASK) |
+ (currY & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT) |
+ (currZ & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT + BLOCK_EXPLOSION_CACHE_SHIFT);
+ ExplosionBlockCache cachedBlock = blockCache[cacheKey];
+ if (cachedBlock == null || cachedBlock.key != key) {
+ blockCache[cacheKey] = cachedBlock = this.getOrCacheExplosionBlock(currX, currY, currZ, key, false);
+ }
+
+ final BlockState blockState = cachedBlock.blockState;
+ if (blockState != null && !blockState.emptyCollisionShape()) {
+ net.minecraft.world.phys.shapes.VoxelShape collision = cachedBlock.cachedCollisionShape;
+ if (collision == null) {
+ collision = blockState.getConstantCollisionShape();
+ if (collision == null) {
+ collision = blockState.getCollisionShape(this.level, currPos, context);
+ if (!context.isDelegated()) {
+ // if it was not delegated during this call, assume that for any future ones it will not be delegated
+ // again, and cache the result
+ cachedBlock.cachedCollisionShape = collision;
+ }
+ } else {
+ cachedBlock.cachedCollisionShape = collision;
+ }
+ }
+
+ if (!collision.isEmpty() && collision.clip(from, to, currPos) != null) {
+ return true;
+ }
+ }
+
+ if (normalizedCurrX > 1.0 && normalizedCurrY > 1.0 && normalizedCurrZ > 1.0) {
+ return false;
+ }
+
+ // inc the smallest normalized coordinate
+
+ if (normalizedCurrX < normalizedCurrY) {
+ if (normalizedCurrX < normalizedCurrZ) {
+ currX += dx;
+ normalizedCurrX += normalizedDiffX;
+ } else {
+ // x < y && x >= z <--> z < y && z <= x
+ currZ += dz;
+ normalizedCurrZ += normalizedDiffZ;
+ }
+ } else if (normalizedCurrY < normalizedCurrZ) {
+ // y <= x && y < z
+ currY += dy;
+ normalizedCurrY += normalizedDiffY;
+ } else {
+ // y <= x && z <= y <--> z <= y && z <= x
+ currZ += dz;
+ normalizedCurrZ += normalizedDiffZ;
+ }
+ }
+ }
+
+ private float getSeenFraction(final Vec3 source, final Entity target,
+ final ExplosionBlockCache[] blockCache,
+ final BlockPos.MutableBlockPos blockPos) {
+ final AABB boundingBox = target.getBoundingBox();
+ final double diffX = boundingBox.maxX - boundingBox.minX;
+ final double diffY = boundingBox.maxY - boundingBox.minY;
+ final double diffZ = boundingBox.maxZ - boundingBox.minZ;
+
+ final double incX = 1.0 / (diffX * 2.0 + 1.0);
+ final double incY = 1.0 / (diffY * 2.0 + 1.0);
+ final double incZ = 1.0 / (diffZ * 2.0 + 1.0);
+
+ if (incX < 0.0 || incY < 0.0 || incZ < 0.0) {
+ return 0.0f;
+ }
+
+ final double offX = (1.0 - Math.floor(1.0 / incX) * incX) * 0.5 + boundingBox.minX;
+ final double offY = boundingBox.minY;
+ final double offZ = (1.0 - Math.floor(1.0 / incZ) * incZ) * 0.5 + boundingBox.minZ;
+
+ final io.papermc.paper.util.CollisionUtil.LazyEntityCollisionContext context = new io.papermc.paper.util.CollisionUtil.LazyEntityCollisionContext(target);
+
+ int totalRays = 0;
+ int missedRays = 0;
+
+ for (double dx = 0.0; dx <= 1.0; dx += incX) {
+ final double fromX = Math.fma(dx, diffX, offX);
+ for (double dy = 0.0; dy <= 1.0; dy += incY) {
+ final double fromY = Math.fma(dy, diffY, offY);
+ for (double dz = 0.0; dz <= 1.0; dz += incZ) {
+ ++totalRays;
+
+ final Vec3 from = new Vec3(
+ fromX,
+ fromY,
+ Math.fma(dz, diffZ, offZ)
+ );
+
+ if (!this.clipsAnything(from, source, context, blockCache, blockPos)) {
+ ++missedRays;
+ }
+ }
+ }
+ }
+
+ return (float)missedRays / (float)totalRays;
+ }
+ // Paper end - optimise collisions
+
private ExplosionDamageCalculator makeDamageCalculator(@Nullable Entity entity) {
return (ExplosionDamageCalculator) (entity == null ? Explosion.EXPLOSION_DAMAGE_CALCULATOR : new EntityBasedExplosionDamageCalculator(entity));
}
@@ -149,40 +414,90 @@ public class Explosion {
int i;
int j;
- for (int k = 0; k < 16; ++k) {
- for (i = 0; i < 16; ++i) {
- for (j = 0; j < 16; ++j) {
- if (k == 0 || k == 15 || i == 0 || i == 15 || j == 0 || j == 15) {
- double d0 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
- double d1 = (double) ((float) i / 15.0F * 2.0F - 1.0F);
- double d2 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
- double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
-
- d0 /= d3;
- d1 /= d3;
- d2 /= d3;
+ // Paper start - optimise explosions
+ this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>();
+
+ this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
+ java.util.Arrays.fill(this.chunkPosCache, ChunkPos.INVALID_CHUNK_POS);
+
+ this.chunkCache = new net.minecraft.world.level.chunk.LevelChunk[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
+
+ final ExplosionBlockCache[] blockCache = new ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH];
+ // use initial cache value that is most likely to be used: the source position
+ final ExplosionBlockCache initialCache;
+ {
+ final int blockX = Mth.floor(this.x);
+ final int blockY = Mth.floor(this.y);
+ final int blockZ = Mth.floor(this.z);
+
+ final long key = BlockPos.asLong(blockX, blockY, blockZ);
+
+ initialCache = this.getOrCacheExplosionBlock(blockX, blockY, blockZ, key, true);
+ }
+ // only ~1/3rd of the loop iterations in vanilla will result in a ray, as it is iterating the perimeter of
+ // a 16x16x16 cube
+ // we can cache the rays and their normals as well, so that we eliminate the excess iterations / checks and
+ // calculations in one go
+ // additional aggressive caching of block retrieval is very significant, as at low power (i.e tnt) most
+ // block retrievals are not unique
+ for (int ray = 0, len = CACHED_RAYS.length; ray < len;) {
+ {
+ {
+ {
+ ExplosionBlockCache cachedBlock = initialCache;
+
+ double d0 = CACHED_RAYS[ray];
+ double d1 = CACHED_RAYS[ray + 1];
+ double d2 = CACHED_RAYS[ray + 2];
+ ray += 3;
+ // Paper end - optimise explosions
float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F);
double d4 = this.x;
double d5 = this.y;
double d6 = this.z;
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
- BlockPos blockposition = BlockPos.containing(d4, d5, d6);
- BlockState iblockdata = this.level.getBlockState(blockposition);
- if (!iblockdata.isDestroyable()) continue; // Paper
- FluidState fluid = iblockdata.getFluidState(); // Paper
+ // Paper start - optimise explosions
+ final int blockX = Mth.floor(d4);
+ final int blockY = Mth.floor(d5);
+ final int blockZ = Mth.floor(d6);
+
+ final long key = BlockPos.asLong(blockX, blockY, blockZ);
+
+ if (cachedBlock.key != key) {
+ final int cacheKey =
+ (blockX & BLOCK_EXPLOSION_CACHE_MASK) |
+ (blockY & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT) |
+ (blockZ & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT + BLOCK_EXPLOSION_CACHE_SHIFT);
+ cachedBlock = blockCache[cacheKey];
+ if (cachedBlock == null || cachedBlock.key != key) {
+ blockCache[cacheKey] = cachedBlock = this.getOrCacheExplosionBlock(blockX, blockY, blockZ, key, true);
+ }
+ }
- if (!this.level.isInWorldBounds(blockposition)) {
+ if (cachedBlock.outOfWorld) {
break;
}
- Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance(this, this.level, blockposition, iblockdata, fluid);
+ BlockPos blockposition = cachedBlock.immutablePos;
+ BlockState iblockdata = cachedBlock.blockState;
+ // Paper end - optimise explosions
- if (optional.isPresent()) {
- f -= ((Float) optional.get() + 0.3F) * 0.3F;
- }
+ if (!iblockdata.isDestroyable()) continue; // Paper
+ // Paper - optimise explosions
- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) {
+ // Paper - optimise explosions
+
+ f -= cachedBlock.resistance; // Paper - optimise explosions
+
+ if (f > 0.0F && cachedBlock.shouldExplode == null) { // Paper - optimise explosions
+ // Paper start - optimise explosions
+ // note: we expect shouldBlockExplode to be pure with respect to power, as Vanilla currently is.
+ // basically, it is unused, which allows us to cache the result
+ final boolean shouldExplode = this.damageCalculator.shouldBlockExplode(this, this.level, cachedBlock.immutablePos, cachedBlock.blockState, f);
+ cachedBlock.shouldExplode = shouldExplode ? Boolean.TRUE : Boolean.FALSE;
+ if (shouldExplode && (this.fire || !cachedBlock.blockState.isAir())) {
+ // Paper end - optimise explosions
set.add(blockposition);
// Paper start - prevent headless pistons from forming
if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
@@ -193,11 +508,12 @@ public class Explosion {
}
}
// Paper end
+ } // Paper - optimise explosions
}
- d4 += d0 * 0.30000001192092896D;
- d5 += d1 * 0.30000001192092896D;
- d6 += d2 * 0.30000001192092896D;
+ d4 += d0; // Paper - optimise explosions
+ d5 += d1; // Paper - optimise explosions
+ d6 += d2; // Paper - optimise explosions
}
}
}
@@ -217,6 +533,8 @@ public class Explosion {
Vec3 vec3d = new Vec3(this.x, this.y, this.z);
Iterator iterator = list.iterator();
+ final BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos(); // Paper - optimise explosions
+
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
@@ -233,7 +551,7 @@ public class Explosion {
d8 /= d11;
d9 /= d11;
d10 /= d11;
- double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
+ double d12 = this.getBlockDensity(vec3d, entity, blockCache, blockPos); // Paper - Optimize explosions // Paper - optimise explosions
double d13 = (1.0D - d7) * d12;
// CraftBukkit start
@@ -256,7 +574,7 @@ public class Explosion {
// Calculate damage separately for each EntityComplexPart
double d7part;
if (list.contains(entityComplexPart) && (d7part = Math.sqrt(entityComplexPart.distanceToSqr(vec3d)) / f2) <= 1.0D) {
- double d13part = (1.0D - d7part) * Explosion.getSeenPercent(vec3d, entityComplexPart);
+ double d13part = (1.0D - d7part) * this.getSeenFraction(vec3d, entityComplexPart, blockCache, blockPos); // Paper - optimise explosions
entityComplexPart.hurt(this.getDamageSource(), (float) ((int) ((d13part * d13part + d13part) / 2.0D * 7.0D * (double) f2 + 1.0D)));
}
}
@@ -297,6 +615,10 @@ public class Explosion {
}
}
+ this.blockCache = null; // Paper - optimise explosions
+ this.chunkPosCache = null; // Paper - optimise explosions
+ this.chunkCache = null; // Paper - optimise explosions
+
}
public void finalizeExplosion(boolean particles) {
@@ -526,14 +848,14 @@ public class Explosion {
private BlockInteraction() {}
}
// Paper start - Optimize explosions
- private float getBlockDensity(Vec3 vec3d, Entity entity) {
+ private float getBlockDensity(Vec3 vec3d, Entity entity, ExplosionBlockCache[] blockCache, BlockPos.MutableBlockPos blockPos) { // Paper - optimise explosions
if (!this.level.paperConfig().environment.optimizeExplosions) {
- return getSeenPercent(vec3d, entity);
+ return this.getSeenFraction(vec3d, entity, blockCache, blockPos); // Paper - optimise explosions
}
CacheKey key = new CacheKey(this, entity.getBoundingBox());
Float blockDensity = this.level.explosionDensityCache.get(key);
if (blockDensity == null) {
- blockDensity = getSeenPercent(vec3d, entity);
+ blockDensity = this.getSeenFraction(vec3d, entity, blockCache, blockPos); // Paper - optimise explosions;
this.level.explosionDensityCache.put(key, blockDensity);
}