/net/minecraft/world/entity/decoration/

Note that a method was removed on Armorstand for a bug fix that makes literally zero sense, probably very old.
Also added and fixed the logic for leashes, as any entity can hold leashes but anything can be leashed.

Also very sad hack used to detect if the value was set.

/net/minecraft/world/level/block/entity/trialspawner/

/net/minecraft/server/network
This commit is contained in:
Owen1212055
2025-05-29 14:59:10 -04:00
parent ca8da0e3ca
commit e0437448dd
13 changed files with 334 additions and 504 deletions

View File

@@ -1,69 +0,0 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java b/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
index b40927c73ab847264b1110cd272adc2e8da42526..258696853e9f3539cb44c86343fbec81f6a3e770 100644
--- a/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
+++ b/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
@@ -81,6 +81,15 @@ public class LeashFenceKnotEntity extends BlockAttachedEntity {
for (Leashable leashable : list) {
if (leashable.getLeashHolder() == player) {
+ // CraftBukkit start
+ if (leashable instanceof Entity leashed) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, this, player, hand).isCancelled()) {
+ ((net.minecraft.server.level.ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(leashed, leashable.getLeashHolder()));
+ flag = true; // Also set true when the event is cancelled otherwise it tries to unleash the entities
+ continue;
+ }
+ }
+ // CraftBukkit end
leashable.setLeashedTo(this, true);
flag = true;
}
@@ -88,14 +97,39 @@ public class LeashFenceKnotEntity extends BlockAttachedEntity {
boolean flag1 = false;
if (!flag) {
- this.discard();
- if (player.getAbilities().instabuild) {
+ // CraftBukkit start - Move below
+ // this.discard();
+ boolean die = true;
+ // CraftBukkit end
+ if (true || player.getAbilities().instabuild) { // CraftBukkit - Process for non-creative as well
for (Leashable leashable1 : list) {
if (leashable1.isLeashed() && leashable1.getLeashHolder() == this) {
- leashable1.removeLeash();
+ // CraftBukkit start
+ boolean dropLeash = !player.hasInfiniteMaterials();
+ if (leashable1 instanceof Entity leashed) {
+ // Paper start - Expand EntityUnleashEvent
+ org.bukkit.event.player.PlayerUnleashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(leashed, player, hand, dropLeash);
+ dropLeash = event.isDropLeash();
+ if (event.isCancelled()) {
+ // Paper end - Expand EntityUnleashEvent
+ die = false;
+ continue;
+ }
+ }
+ if (!dropLeash) { // Paper - Expand EntityUnleashEvent
+ leashable1.removeLeash();
+ } else {
+ leashable1.dropLeash();
+ }
+ // CraftBukkit end
flag1 = true;
}
}
+ // CraftBukkit start
+ if (die) {
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
+ }
+ // CraftBukkit end
}
}

View File

@@ -1,46 +0,0 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
index d0a5a5de539c80dbb7a684dc2fb845e3d5e602bd..8073911c2119864685d8fcd56d4f11fd0c340808 100644
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
@@ -238,7 +238,14 @@ public final class TrialSpawner {
nextSpawnData.getEquipment().ifPresent(mob::equip);
}
- if (!level.tryAddFreshEntityWithPassengers(entity)) {
+ // Paper start - TrialSpawnerSpawnEvent + SpawnReason
+ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ return Optional.empty();
+ }
+ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) {
+ // Paper end - TrialSpawnerSpawnEvent + SpawnReason
return Optional.empty();
} else {
TrialSpawner.FlameParticle flameParticle = this.isOminous ? TrialSpawner.FlameParticle.OMINOUS : TrialSpawner.FlameParticle.NORMAL;
@@ -258,6 +265,19 @@ public final class TrialSpawner {
LootParams lootParams = new LootParams.Builder(level).create(LootContextParamSets.EMPTY);
ObjectArrayList<ItemStack> randomItems = lootTable1.getRandomItems(lootParams);
if (!randomItems.isEmpty()) {
+ // CraftBukkit start
+ org.bukkit.event.block.BlockDispenseLootEvent spawnerDispenseLootEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDispenseLootEvent(
+ level,
+ pos,
+ null,
+ randomItems
+ );
+ if (spawnerDispenseLootEvent.isCancelled()) {
+ return;
+ }
+
+ randomItems = new ObjectArrayList<>(spawnerDispenseLootEvent.getDispensedLoot().stream().map(org.bukkit.craftbukkit.inventory.CraftItemStack::asNMSCopy).toList());
+ // CraftBukkit end
for (ItemStack itemStack : randomItems) {
DefaultDispenseItemBehavior.spawnItem(level, itemStack, 2, Direction.UP, Vec3.atBottomCenterOf(pos).relative(Direction.UP, 1.2));
}

View File

@@ -1,19 +0,0 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
index 11db32434437d3e69724d196ab89a9df5aaadeff..f46427af9c55668d1504ae0e4f50179cbe85b0ca 100644
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
@@ -197,7 +197,7 @@ public class TrialSpawnerData {
mob.dropPreservedEquipment(level);
}
- entity.remove(Entity.RemovalReason.DISCARDED);
+ entity.remove(Entity.RemovalReason.DISCARDED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - Add bukkit remove cause;
}
});
if (!spawner.getOminousConfig().spawnPotentialsDefinition().isEmpty()) {

View File

@@ -1,14 +1,6 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef29586198356e2d2600 100644
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -27,31 +27,68 @@ import net.minecraft.util.VisibleForDebug;
@@ -29,30 +_,67 @@
import net.minecraft.util.profiling.Profiler;
import org.slf4j.Logger;
@@ -47,12 +39,13 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
this.keepAliveTime = Util.getMillis();
this.latency = cookie.latency();
this.transferred = cookie.transferred();
- }
+ // CraftBukkit start - add fields and methods
+ this.player = player;
+ this.player.transferCookieConnection = this;
+ this.cserver = server.server;
}
+ }
+
+ public org.bukkit.craftbukkit.entity.CraftPlayer getCraftPlayer() {
+ return this.player.getBukkitEntity();
+ }
@@ -77,11 +70,10 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
+ this.disconnect(reason, cause); // Paper - kick event causes
+ }
+ // CraftBukkit end
+
private void close() {
if (!this.closed) {
this.closedListenerTime = Util.getMillis();
@@ -61,6 +98,12 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -63,6 +_,12 @@
@Override
public void onDisconnect(DisconnectionDetails details) {
@@ -94,7 +86,7 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
if (this.isSingleplayerOwner()) {
LOGGER.info("Stopping singleplayer server as player logged out");
this.server.halt(false);
@@ -80,7 +123,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -82,7 +_,7 @@
this.latency = (this.latency * 3 + i) / 4;
this.keepAlivePending = false;
} else if (!this.isSingleplayerOwner()) {
@@ -103,7 +95,7 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
}
}
@@ -88,30 +131,123 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -90,9 +_,73 @@
public void handlePong(ServerboundPongPacket packet) {
}
@@ -112,6 +104,7 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
+
@Override
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
- }
+ // Paper start
+ if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload(String brand)) {
+ this.player.clientBrandName = brand;
@@ -172,17 +165,19 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
+
+ public final boolean isDisconnected() {
+ return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper - Fix duplication bugs
}
+ }
+ // Paper end
@Override
public void handleResourcePackResponse(ServerboundResourcePackPacket packet) {
public void handleCustomClickAction(ServerboundCustomClickActionPacket packet) {
@@ -105,21 +_,50 @@
PacketUtils.ensureRunningOnSameThread(packet, this, this.server);
if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) {
LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), packet.id());
- this.disconnect(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"));
- }
+ this.disconnect(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"), org.bukkit.event.player.PlayerKickEvent.Cause.RESOURCE_PACK_REJECTION); // Paper - kick event cause
}
+ }
+ // Paper start - adventure pack callbacks
+ // call the callbacks before the previously-existing event so the event has final say
+ final net.kyori.adventure.resource.ResourcePackCallback callback;
@@ -231,7 +226,7 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
} else if (this.checkIfClosed(millis)) {
this.keepAlivePending = true;
this.keepAliveTime = millis;
@@ -126,7 +262,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -134,7 +_,7 @@
private boolean checkIfClosed(long time) {
if (this.closed) {
if (time - this.closedListenerTime >= 15000L) {
@@ -240,10 +235,10 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
}
return false;
@@ -149,6 +285,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -157,6 +_,13 @@
}
public void send(Packet<?> packet, @Nullable PacketSendListener listener) {
public void send(Packet<?> packet, @Nullable ChannelFutureListener channelFutureListener) {
+ // CraftBukkit start
+ if (packet == null || this.processedDisconnect) { // Spigot
+ return;
@@ -254,7 +249,7 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
if (packet.isTerminal()) {
this.close();
}
@@ -165,19 +308,115 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -173,19 +_,115 @@
}
}
@@ -271,6 +266,9 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - kick event causes
public void disconnect(Component reason) {
- this.disconnect(new DisconnectionDetails(reason));
- }
-
- public void disconnect(DisconnectionDetails disconnectionDetails) {
+ // Paper start - kick event causes
+ this.disconnect(reason, org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
+ }
@@ -327,9 +325,8 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
+
+ // Send the possibly modified leave message
+ this.disconnect0(new DisconnectionDetails(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.reason()), disconnectionDetails.report(), disconnectionDetails.bugReportLink()), event.leaveMessage()); // Paper - Adventure & use kick event leave message
}
- public void disconnect(DisconnectionDetails disconnectionDetails) {
+ }
+
+ private void disconnect0(DisconnectionDetails disconnectionDetails, @Nullable net.kyori.adventure.text.Component leaveMessage) { // Paper - use kick event leave message
+ // CraftBukkit end
+ this.player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.KICKED; // Paper - Add API for quit reason
@@ -338,9 +335,11 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
new ClientboundDisconnectPacket(disconnectionDetails.reason()),
PacketSendListener.thenRun(() -> this.connection.disconnect(disconnectionDetails))
);
+ this.onDisconnect(disconnectionDetails, leaveMessage); // CraftBukkit - fire quit instantly // Paper - use kick event leave message
this.connection.setReadOnly();
- this.connection.setReadOnly();
- this.server.executeBlocking(this.connection::handleDisconnection);
- }
+ this.onDisconnect(disconnectionDetails, leaveMessage); // CraftBukkit - fire quit instantly // Paper - use kick event leave message
+ this.connection.setReadOnly();
+ // CraftBukkit - Don't wait
+ this.server.scheduleOnMain(this.connection::handleDisconnection); // Paper
+ }
@@ -368,7 +367,7 @@ index aa2c3c670063f980fce003c1b7df926df8c61f12..186393485396cfe9b1baef2958619835
+ ServerCommonPacketListenerImpl.this.connection.enableAutoRead();
+ }
+ });
}
+ }
+ // Paper end - add proper async disconnect
protected boolean isSingleplayerOwner() {

View File

@@ -1,14 +1,6 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java b/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java
index 8e39d689fc5eb405d76dee0a071b45960f74a25b..2e9eb04c7c4342393c05339906c267bca9ff29b1 100644
--- a/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java
@@ -48,8 +48,10 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis
@@ -48,8 +_,10 @@
@Nullable
private SynchronizeRegistriesTask synchronizeRegistriesTask;
@@ -21,7 +13,7 @@ index 8e39d689fc5eb405d76dee0a071b45960f74a25b..2e9eb04c7c4342393c05339906c267bc
this.gameProfile = cookie.gameProfile();
this.clientInformation = cookie.clientInformation();
}
@@ -61,6 +63,11 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis
@@ -61,6 +_,11 @@
@Override
public void onDisconnect(DisconnectionDetails details) {
@@ -33,7 +25,7 @@ index 8e39d689fc5eb405d76dee0a071b45960f74a25b..2e9eb04c7c4342393c05339906c267bc
LOGGER.info("{} lost connection: {}", this.gameProfile, details.reason().getString());
super.onDisconnect(details);
}
@@ -73,6 +80,12 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis
@@ -73,6 +_,12 @@
public void startConfiguration() {
this.send(new ClientboundCustomPayloadPacket(new BrandPayload(this.server.getServerModName())));
ServerLinks serverLinks = this.server.serverLinks();
@@ -46,7 +38,7 @@ index 8e39d689fc5eb405d76dee0a071b45960f74a25b..2e9eb04c7c4342393c05339906c267bc
if (!serverLinks.isEmpty()) {
this.send(new ClientboundServerLinksPacket(serverLinks.untrust()));
}
@@ -105,6 +118,7 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis
@@ -105,6 +_,7 @@
@Override
public void handleClientInformation(ServerboundClientInformationPacket packet) {
this.clientInformation = packet.information();
@@ -54,7 +46,7 @@ index 8e39d689fc5eb405d76dee0a071b45960f74a25b..2e9eb04c7c4342393c05339906c267bc
}
@Override
@@ -139,16 +153,21 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis
@@ -139,16 +_,22 @@
return;
}
@@ -65,9 +57,10 @@ index 8e39d689fc5eb405d76dee0a071b45960f74a25b..2e9eb04c7c4342393c05339906c267bc
return;
}
- ServerPlayer playerForLogin = playerList.getPlayerForLogin(this.gameProfile, this.clientInformation);
+ ServerPlayer playerForLogin = playerList.getPlayerForLogin(this.gameProfile, this.clientInformation, this.player); // CraftBukkit
playerList.placeNewPlayer(this.connection, playerForLogin, this.createCookie(this.clientInformation));
- ServerPlayer serverPlayer = new ServerPlayer(this.server, this.server.overworld(), this.gameProfile, this.clientInformation);
+ ServerPlayer serverPlayer = this.player; // Paper
+ this.player.updateOptions(this.clientInformation); // Paper - Of course, we reuse the player
playerList.placeNewPlayer(this.connection, serverPlayer, this.createCookie(this.clientInformation));
} catch (Exception var5) {
LOGGER.error("Couldn't place player in world", (Throwable)var5);
+ // Paper start - Debugging

View File

@@ -1,14 +1,6 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc75d3f279b 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -204,6 +204,39 @@ import net.minecraft.world.phys.shapes.Shapes;
@@ -208,6 +_,39 @@
import net.minecraft.world.phys.shapes.VoxelShape;
import org.slf4j.Logger;
@@ -48,7 +40,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
public class ServerGamePacketListenerImpl
extends ServerCommonPacketListenerImpl
implements GameProtocols.Context,
@@ -222,7 +255,9 @@ public class ServerGamePacketListenerImpl
@@ -226,7 +_,9 @@
private int tickCount;
private int ackBlockChangesUpTo = -1;
private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200);
@@ -58,7 +50,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
private double firstGoodX;
private double firstGoodY;
private double firstGoodZ;
@@ -248,23 +283,42 @@ public class ServerGamePacketListenerImpl
@@ -252,23 +_,42 @@
private int receivedMovePacketCount;
private int knownMovePacketCount;
private boolean receivedMovementThisTick;
@@ -103,7 +95,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
@Override
@@ -284,8 +338,8 @@ public class ServerGamePacketListenerImpl
@@ -288,8 +_,8 @@
this.knownMovePacketCount = this.receivedMovePacketCount;
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) {
@@ -114,7 +106,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
return;
}
} else {
@@ -303,8 +357,8 @@ public class ServerGamePacketListenerImpl
@@ -307,8 +_,8 @@
this.vehicleLastGoodZ = this.lastVehicle.getZ();
if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) {
if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) {
@@ -125,7 +117,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
return;
}
} else {
@@ -320,11 +374,20 @@ public class ServerGamePacketListenerImpl
@@ -324,11 +_,20 @@
this.keepConnectionAlive();
this.chatSpamThrottler.tick();
this.dropSpamThrottler.tick();
@@ -135,6 +127,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
&& this.server.getPlayerIdleTimeout() > 0
- && Util.getMillis() - this.player.getLastActionTime() > this.server.getPlayerIdleTimeout() * 1000L * 60L) {
- this.disconnect(Component.translatable("multiplayer.disconnect.idling"));
- }
+ && Util.getMillis() - this.player.getLastActionTime() > this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits
+ this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
+ this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
@@ -143,15 +136,15 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ if (!this.hasLoggedExpiry && this.chatSession != null && this.chatSession.profilePublicKey().data().hasExpired()) {
+ LOGGER.info("Player profile key for {} has expired!", this.player.getName().getString());
+ this.hasLoggedExpiry = true;
}
+ }
+ // Paper end - Prevent causing expired keys from impacting new joins
}
private int getMaximumFlyingTicks(Entity entity) {
@@ -384,6 +447,12 @@ public class ServerGamePacketListenerImpl
@@ -388,11 +_,22 @@
@Override
public void handlePlayerInput(ServerboundPlayerInputPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ // CraftBukkit start
+ if (!packet.input().equals(this.player.getLastClientInput())) {
+ PlayerInputEvent event = new PlayerInputEvent(this.player.getBukkitEntity(), new org.bukkit.craftbukkit.CraftInput(packet.input()));
@@ -159,11 +152,21 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ }
+ // CraftBukkit end
this.player.setLastClientInput(packet.input());
if (this.player.hasClientLoaded()) {
this.player.resetLastActionTime();
this.player.setShiftKeyDown(packet.input().shift());
}
+ // Paper start - Add option to make parrots stay
+ if (packet.input().shift() && this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
+ this.player.removeEntitiesOnShoulder();
+ }
+ // Paper end - Add option to make parrots stay
}
@@ -403,17 +472,29 @@ public class ServerGamePacketListenerImpl
private static boolean containsInvalidValues(double x, double y, double z, float yRot, float xRot) {
@@ -411,17 +_,29 @@
public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
if (containsInvalidValues(packet.position().x(), packet.position().y(), packet.position().z(), packet.yRot(), packet.xRot())) {
- this.disconnect(Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"));
+ this.disconnect(Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause
@@ -175,7 +178,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ }
+ // Paper end - Don't allow vehicle movement from players while teleporting
if (rootVehicle != this.player && rootVehicle.getControllingPassenger() == this.player && rootVehicle == this.lastVehicle) {
ServerLevel serverLevel = this.player.serverLevel();
ServerLevel serverLevel = this.player.level();
+ // CraftBukkit - store current player position
+ double prevX = this.player.getX();
+ double prevY = this.player.getY();
@@ -195,7 +198,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
float f = Mth.wrapDegrees(packet.yRot());
float f1 = Mth.wrapDegrees(packet.xRot());
double d3 = d - this.vehicleFirstGoodX;
@@ -421,7 +502,52 @@ public class ServerGamePacketListenerImpl
@@ -429,7 +_,52 @@
double d5 = d2 - this.vehicleFirstGoodZ;
double d6 = rootVehicle.getDeltaMovement().lengthSqr();
double d7 = d3 * d3 + d4 * d4 + d5 * d5;
@@ -249,48 +252,34 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
LOGGER.warn(
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
);
@@ -430,15 +556,16 @@ public class ServerGamePacketListenerImpl
@@ -438,9 +_,9 @@
}
boolean flag = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
AABB boundingBox = rootVehicle.getBoundingBox();
- d3 = d - this.vehicleLastGoodX;
- d4 = d1 - this.vehicleLastGoodY;
- d5 = d2 - this.vehicleLastGoodZ;
+ d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above
+ d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above
+ d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above
boolean flag1 = rootVehicle.verticalCollisionBelow;
boolean flag = rootVehicle.verticalCollisionBelow;
if (rootVehicle instanceof LivingEntity livingEntity && livingEntity.onClimbable()) {
livingEntity.resetFallDistance();
}
rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
+ double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost
d3 = d - rootVehicle.getX();
d4 = d1 - rootVehicle.getY();
if (d4 > -0.5 || d4 < 0.5) {
@@ -448,27 +575,80 @@ public class ServerGamePacketListenerImpl
@@ -457,7 +_,7 @@
d5 = d2 - rootVehicle.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false;
boolean flag1 = false;
- if (d7 > 0.0625) {
+ if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
flag2 = true;
flag1 = true;
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
}
@@ -471,6 +_,57 @@
}
rootVehicle.absSnapTo(d, d1, d2, f, f1);
+ this.player.absSnapTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
if (flag && (flag2 || !flag3)) {
rootVehicle.absSnapTo(x, y, z, f, f1);
+ this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
rootVehicle.removeLatestMovementRecordingBatch();
return;
}
+ // CraftBukkit start - fire PlayerMoveEvent
+ // CraftBukkit start - fire PlayerMoveEvent TODO: this should be removed.
+ this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // Paper - TODO: This breaks alot of stuff
+ org.bukkit.entity.Player player = this.getCraftPlayer();
+ if (!this.hasMoved) {
+ this.lastPosX = prevX;
@@ -340,20 +329,11 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ }
+ }
+ // CraftBukkit end
+
this.player.serverLevel().getChunkSource().move(this.player);
this.player.level().getChunkSource().move(this.player);
Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z);
this.handlePlayerKnownMovement(vec3);
rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3);
rootVehicle.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.onGround());
this.player.checkMovementStatistics(vec3.x, vec3.y, vec3.z);
- this.clientVehicleIsFloating = d4 >= -0.03125
+ this.clientVehicleIsFloating = verticalDelta >= -0.03125 // Paper - Decompile fix
&& !flag1
&& !this.server.isFlightAllowed()
&& !rootVehicle.isNoGravity()
@@ -491,12 +671,12 @@ public class ServerGamePacketListenerImpl
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
@@ -501,12 +_,12 @@
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
if (packet.getId() == this.awaitingTeleport) {
if (this.awaitingPositionFromClient == null) {
- this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"));
@@ -367,7 +347,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.awaitingPositionFromClient.x,
this.awaitingPositionFromClient.y,
this.awaitingPositionFromClient.z,
@@ -508,12 +688,20 @@ public class ServerGamePacketListenerImpl
@@ -518,12 +_,20 @@
this.lastGoodZ = this.awaitingPositionFromClient.z;
this.player.hasChangedDimension();
this.awaitingPositionFromClient = null;
@@ -377,7 +357,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
@Override
public void handleAcceptPlayerLoad(ServerboundPlayerLoadedPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ // Paper start - PlayerLoadedWorldEvent
+ if (this.player.hasClientLoaded()) {
+ return;
@@ -388,15 +368,15 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.player.setClientLoaded(true);
}
@@ -535,6 +723,7 @@ public class ServerGamePacketListenerImpl
@@ -545,6 +_,7 @@
@Override
public void handleRecipeBookChangeSettingsPacket(ServerboundRecipeBookChangeSettingsPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ CraftEventFactory.callRecipeBookSettingsEvent(this.player, packet.getBookType(), packet.isOpen(), packet.isFiltering()); // CraftBukkit
this.player.getRecipeBook().setBookSetting(packet.getBookType(), packet.isOpen(), packet.isFiltering());
}
@@ -550,25 +739,110 @@ public class ServerGamePacketListenerImpl
@@ -560,25 +_,110 @@
}
}
@@ -407,8 +387,8 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+
@Override
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); // Paper - AsyncTabCompleteEvent; run this async
+ // CraftBukkit start
+ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits
+ this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect
@@ -512,8 +492,8 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
);
}
@@ -578,7 +852,7 @@ public class ServerGamePacketListenerImpl
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
@@ -588,7 +_,7 @@
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
if (!this.server.isCommandBlockEnabled()) {
this.player.sendSystemMessage(Component.translatable("advMode.notEnabled"));
- } else if (!this.player.canUseGameMasterBlocks()) {
@@ -521,8 +501,8 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.player.sendSystemMessage(Component.translatable("advMode.notAllowed"));
} else {
BaseCommandBlock baseCommandBlock = null;
@@ -633,7 +907,7 @@ public class ServerGamePacketListenerImpl
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
@@ -643,7 +_,7 @@
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
if (!this.server.isCommandBlockEnabled()) {
this.player.sendSystemMessage(Component.translatable("advMode.notEnabled"));
- } else if (!this.player.canUseGameMasterBlocks()) {
@@ -530,7 +510,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.player.sendSystemMessage(Component.translatable("advMode.notAllowed"));
} else {
BaseCommandBlock commandBlock = packet.getCommandBlock(this.player.level());
@@ -661,11 +935,11 @@ public class ServerGamePacketListenerImpl
@@ -671,11 +_,11 @@
boolean flag = this.player.hasInfiniteMaterials() && packet.includeData();
ItemStack cloneItemStack = blockState.getCloneItemStack(serverLevel, blockPos, flag);
if (!cloneItemStack.isEmpty()) {
@@ -544,7 +524,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
}
@@ -689,27 +963,40 @@ public class ServerGamePacketListenerImpl
@@ -702,27 +_,40 @@
if (entityOrPart != null && this.player.canInteractWithEntity(entityOrPart, 3.0)) {
ItemStack pickResult = entityOrPart.getPickResult();
if (pickResult != null && !pickResult.isEmpty()) {
@@ -585,14 +565,14 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ inventory.addAndPickItem(stack, event.getTargetSlot()); // Paper - Add PlayerPickItemEvent
}
this.player.connection.send(new ClientboundSetHeldSlotPacket(inventory.getSelectedSlot()));
this.send(new ClientboundSetHeldSlotPacket(inventory.getSelectedSlot()));
this.player.inventoryMenu.broadcastChanges();
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
}
}
@@ -887,6 +1174,13 @@ public class ServerGamePacketListenerImpl
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
@@ -900,6 +_,13 @@
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
int item = packet.getItem();
if (this.player.containerMenu instanceof MerchantMenu merchantMenu) {
+ // CraftBukkit start
@@ -605,7 +585,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
if (!merchantMenu.stillValid(this.player)) {
LOGGER.debug("Player {} interacted with invalid menu {}", this.player, merchantMenu);
return;
@@ -899,6 +1193,51 @@ public class ServerGamePacketListenerImpl
@@ -912,6 +_,51 @@
@Override
public void handleEditBook(ServerboundEditBookPacket packet) {
@@ -657,7 +637,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
int slot = packet.slot();
if (Inventory.isHotbarSlot(slot) || slot == 40) {
List<String> list = Lists.newArrayList();
@@ -913,10 +1252,14 @@ public class ServerGamePacketListenerImpl
@@ -926,10 +_,14 @@
}
private void updateBookContents(List<FilteredText> pages, int index) {
@@ -673,7 +653,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
@@ -930,7 +1273,8 @@ public class ServerGamePacketListenerImpl
@@ -943,7 +_,8 @@
DataComponents.WRITTEN_BOOK_CONTENT,
new WrittenBookContent(this.filterableFromOutgoing(title), this.player.getName().getString(), 0, list, true)
);
@@ -683,14 +663,14 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
@@ -974,27 +1318,35 @@ public class ServerGamePacketListenerImpl
@@ -991,27 +_,35 @@
public void handleMovePlayer(ServerboundMovePlayerPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
if (containsInvalidValues(packet.getX(0.0), packet.getY(0.0), packet.getZ(0.0), packet.getYRot(0.0F), packet.getXRot(0.0F))) {
- this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"));
+ this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
} else {
ServerLevel serverLevel = this.player.serverLevel();
ServerLevel serverLevel = this.player.level();
- if (!this.player.wonGame) {
+ if (!this.player.wonGame && !this.player.isImmobile()) { // CraftBukkit
if (this.tickCount == 0) {
@@ -713,7 +693,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ double d2 = clampHorizontal(packet.getZ(this.player.getZ())); final double toZ = d2; // Paper - OBFHELPER
if (this.player.isPassenger()) {
this.player.absSnapTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
this.player.serverLevel().getChunkSource().move(this.player);
this.player.level().getChunkSource().move(this.player);
+ this.allowedPlayerTicks = 20; // CraftBukkit
} else {
+ // CraftBukkit - Make sure the move is valid but then reset it for plugins to modify
@@ -726,7 +706,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
double x = this.player.getX();
double y = this.player.getY();
double z = this.player.getZ();
@@ -1003,6 +1355,16 @@ public class ServerGamePacketListenerImpl
@@ -1020,6 +_,16 @@
double d5 = d2 - this.firstGoodZ;
double d6 = this.player.getDeltaMovement().lengthSqr();
double d7 = d3 * d3 + d4 * d4 + d5 * d5;
@@ -743,7 +723,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
if (this.player.isSleeping()) {
if (d7 > 1.0) {
this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
@@ -1012,36 +1374,109 @@ public class ServerGamePacketListenerImpl
@@ -1029,36 +_,108 @@
if (serverLevel.tickRateManager().runsNormally()) {
this.receivedMovePacketCount++;
int i = this.receivedMovePacketCount - this.knownMovePacketCount;
@@ -860,11 +840,10 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ return; // ... thanks Mojang for letting move calls teleport across dimensions.
+ }
+ // Paper end - prevent position desync
+ double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost
double verticalDelta = d4;
d3 = d - this.player.getX();
d4 = d1 - this.player.getY();
if (d4 > -0.5 || d4 < 0.5) {
@@ -1050,23 +1485,104 @@ public class ServerGamePacketListenerImpl
@@ -1068,20 +_,100 @@
d5 = d2 - this.player.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5;
@@ -885,23 +864,25 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ if (event.getLogWarning())
+ // Paper end
LOGGER.warn("{} moved wrongly!", this.player.getName().getString());
+ } // Paper
}
- }
-
- if (this.player.noPhysics
- || this.player.isSleeping()
- || (!flag2 || !serverLevel.noCollision(this.player, boundingBox))
- && !this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2)) {
- && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2)) {
+ } // Paper
+ }
+
+ // Paper start - Add fail move event
+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && serverLevel.noCollision(this.player, boundingBox) || this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2));
+ if (teleportBack) {
+ boolean allowMovement = this.player.noPhysics || this.player.isSleeping() || (!movedWrongly || !serverLevel.noCollision(this.player, boundingBox)) && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2);
+ if (!allowMovement) {
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
+ toX, toY, toZ, toYaw, toPitch, false);
+ if (event.isAllowed()) {
+ teleportBack = false;
+ allowMovement = true;
+ }
+ }
+ if (!teleportBack) {
+ if (allowMovement) {
+ // Paper end - Add fail move event
+ // CraftBukkit start - fire PlayerMoveEvent
+ // Reset to old location first
@@ -916,7 +897,6 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ this.lastPitch = prevPitch;
+ this.hasMoved = true;
+ }
+
+ Location from = new Location(player.getWorld(), this.lastPosX, this.lastPosY, this.lastPosZ, this.lastYaw, this.lastPitch); // Get the Players previous Event location.
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
+
@@ -969,24 +949,20 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ return;
+ }
+ }
+ // CraftBukkit end
+ // Paper end
this.player.absSnapTo(d, d1, d2, f, f1);
boolean isAutoSpinAttack = this.player.isAutoSpinAttack();
- this.clientIsFloating = d4 >= -0.03125
+ this.clientIsFloating = verticalDelta >= -0.03125 // Paper - Decompile fix
&& !flag1
&& !this.player.isSpectator()
&& !this.server.isFlightAllowed()
@@ -1098,7 +1614,7 @@ public class ServerGamePacketListenerImpl
this.clientIsFloating = verticalDelta >= -0.03125
@@ -1116,7 +_,7 @@
this.lastGoodY = this.player.getY();
this.lastGoodZ = this.player.getZ();
} else {
- this.teleport(x, y, z, f, f1);
+ this.internalTeleport(x, y, z, f, f1); // 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() - x, this.player.getY() - y, this.player.getZ() - z, packet.isOnGround());
this.player.removeLatestMovementRecordingBatch();
this.player.removeLatestMovementRecording();
}
@@ -1134,6 +1650,7 @@ public class ServerGamePacketListenerImpl
@@ -1152,6 +_,7 @@
this.player.getXRot()
);
}
@@ -994,7 +970,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
return true;
} else {
@@ -1157,10 +1674,77 @@ public class ServerGamePacketListenerImpl
@@ -1175,10 +_,77 @@
}
public void teleport(double x, double y, double z, float yaw, float pitch) {
@@ -1073,7 +1049,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.awaitingTeleportTime = this.tickCount;
if (++this.awaitingTeleport == Integer.MAX_VALUE) {
this.awaitingTeleport = 0;
@@ -1168,12 +1752,20 @@ public class ServerGamePacketListenerImpl
@@ -1186,12 +_,20 @@
this.player.teleportSetPosition(posMoveRotation, relatives);
this.awaitingPositionFromClient = this.player.position();
@@ -1084,17 +1060,17 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ this.lastYaw = this.player.getYRot();
+ this.lastPitch = this.player.getXRot();
+ // CraftBukkit end
this.player.connection.send(ClientboundPlayerPositionPacket.of(this.awaitingTeleport, posMoveRotation, relatives));
this.send(ClientboundPlayerPositionPacket.of(this.awaitingTeleport, posMoveRotation, relatives));
}
@Override
public void handlePlayerAction(ServerboundPlayerActionPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
if (this.player.hasClientLoaded()) {
BlockPos pos = packet.getPos();
this.player.resetLastActionTime();
@@ -1182,32 +1774,95 @@ public class ServerGamePacketListenerImpl
@@ -1200,32 +_,94 @@
case SWAP_ITEM_WITH_OFFHAND:
if (!this.player.isSpectator()) {
ItemStack itemInHand = this.player.getItemInHand(InteractionHand.OFF_HAND);
@@ -1172,7 +1148,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ this.player.gameMode.captureSentBlockEntities = true;
+ // Paper end - Send block entities after destroy prediction
this.player.gameMode.handleBlockBreakAction(pos, action, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence());
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
- this.ackBlockChangesUpTo(packet.getSequence());
+ // Paper start - Send block entities after destroy prediction
+ this.player.gameMode.captureSentBlockEntities = false;
+ // If a block entity was modified speedup the block change ack to avoid the block entity
@@ -1193,7 +1169,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
return;
default:
throw new IllegalArgumentException("Invalid player action");
@@ -1224,9 +1879,31 @@ public class ServerGamePacketListenerImpl
@@ -1242,9 +_,31 @@
}
}
@@ -1219,13 +1195,13 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+
@Override
public void handleUseItemOn(ServerboundUseItemOnPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
+ if (!this.checkLimit(packet.timestamp)) return; // Spigot - check limit
if (this.player.hasClientLoaded()) {
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
ServerLevel serverLevel = this.player.serverLevel();
@@ -1235,6 +1912,11 @@ public class ServerGamePacketListenerImpl
this.ackBlockChangesUpTo(packet.getSequence());
ServerLevel serverLevel = this.player.level();
@@ -1253,6 +_,11 @@
if (itemInHand.isItemEnabled(serverLevel.enabledFeatures())) {
BlockHitResult hitResult = packet.getHitResult();
Vec3 location = hitResult.getLocation();
@@ -1237,7 +1213,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
BlockPos blockPos = hitResult.getBlockPos();
if (this.player.canInteractWithBlock(blockPos, 1.0)) {
Vec3 vec3 = location.subtract(Vec3.atCenterOf(blockPos));
@@ -1244,7 +1926,8 @@ public class ServerGamePacketListenerImpl
@@ -1262,7 +_,8 @@
this.player.resetLastActionTime();
int maxY = this.player.level().getMaxY();
if (blockPos.getY() <= maxY) {
@@ -1247,7 +1223,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
InteractionResult interactionResult = this.player.gameMode.useItemOn(this.player, serverLevel, itemInHand, hand, hitResult);
if (interactionResult.consumesAction()) {
CriteriaTriggers.ANY_BLOCK_USE.trigger(this.player, hitResult.getBlockPos(), itemInHand.copy());
@@ -1257,10 +1940,10 @@ public class ServerGamePacketListenerImpl
@@ -1275,10 +_,10 @@
Component component = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED);
this.player.sendSystemMessage(component, true);
} else if (interactionResult instanceof InteractionResult.Success success
@@ -1260,10 +1236,10 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
} else {
Component component1 = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED);
this.player.sendSystemMessage(component1, true);
@@ -1268,13 +1951,7 @@ public class ServerGamePacketListenerImpl
@@ -1286,13 +_,8 @@
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos));
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction)));
this.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos));
this.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction)));
- } else {
- LOGGER.warn(
- "Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.",
@@ -1272,19 +1248,20 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
- blockPos
- );
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
+ // Paper - Remove unused warning
}
}
}
@@ -1284,6 +1961,8 @@ public class ServerGamePacketListenerImpl
@@ -1302,6 +_,8 @@
@Override
public void handleUseItem(ServerboundUseItemPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
+ if (!this.checkLimit(packet.timestamp)) return; // Spigot - check limit
if (this.player.hasClientLoaded()) {
this.ackBlockChangesUpTo(packet.getSequence());
ServerLevel serverLevel = this.player.serverLevel();
@@ -1297,6 +1976,48 @@ public class ServerGamePacketListenerImpl
ServerLevel serverLevel = this.player.level();
@@ -1315,6 +_,48 @@
this.player.absSnapRotationTo(f, f1);
}
@@ -1333,7 +1310,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
if (this.player.gameMode.useItem(this.player, serverLevel, itemInHand, hand) instanceof InteractionResult.Success success
&& success.swingSource() == InteractionResult.SwingSource.SERVER) {
this.player.swing(hand, true);
@@ -1312,7 +2033,7 @@ public class ServerGamePacketListenerImpl
@@ -1330,7 +_,7 @@
for (ServerLevel serverLevel : this.server.getAllLevels()) {
Entity entity = packet.getEntity(serverLevel);
if (entity != null) {
@@ -1342,7 +1319,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
return;
}
}
@@ -1329,24 +2050,54 @@ public class ServerGamePacketListenerImpl
@@ -1347,24 +_,54 @@
@Override
public void onDisconnect(DisconnectionDetails details) {
@@ -1400,10 +1377,10 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
throw new IllegalArgumentException("Expected packet sequence nr >= 0");
} else {
this.ackBlockChangesUpTo = Math.max(sequence, this.ackBlockChangesUpTo);
@@ -1356,20 +2107,38 @@ public class ServerGamePacketListenerImpl
@@ -1374,20 +_,38 @@
@Override
public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
if (packet.getSlot() >= 0 && packet.getSlot() < Inventory.getSelectionSize()) {
+ if (packet.getSlot() == this.player.getInventory().getSelectedSlot()) { return; } // Paper - don't fire itemheldevent when there wasn't a slot change
@@ -1439,7 +1416,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
Optional<LastSeenMessages> optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages());
if (!optional.isEmpty()) {
this.tryHandleChat(packet.message(), () -> {
@@ -1381,25 +2150,45 @@ public class ServerGamePacketListenerImpl
@@ -1399,25 +_,45 @@
return;
}
@@ -1492,7 +1469,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
ParseResults<CommandSourceStack> parseResults = this.parseCommand(command);
if (this.server.enforceSecureProfile() && SignableCommand.hasSignableArguments(parseResults)) {
LOGGER.error(
@@ -1416,28 +2205,57 @@ public class ServerGamePacketListenerImpl
@@ -1434,28 +_,57 @@
Optional<LastSeenMessages> optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages());
if (!optional.isEmpty()) {
this.tryHandleChat(packet.command(), () -> {
@@ -1553,7 +1530,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) {
@@ -1501,14 +2319,20 @@ public class ServerGamePacketListenerImpl
@@ -1519,14 +_,20 @@
return dispatcher.parse(command, this.player.createCommandSourceStack());
}
@@ -1578,7 +1555,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
@@ -1520,7 +2344,7 @@ public class ServerGamePacketListenerImpl
@@ -1538,7 +_,7 @@
var10000 = Optional.of(lastSeenMessages);
} catch (LastSeenMessagesValidator.ValidationException var5) {
LOGGER.error("Failed to validate message acknowledgements from {}: {}", this.player.getName().getString(), var5.getMessage());
@@ -1587,7 +1564,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
return Optional.empty();
}
@@ -1538,22 +2362,81 @@ public class ServerGamePacketListenerImpl
@@ -1556,22 +_,81 @@
return false;
}
@@ -1675,7 +1652,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
@@ -1564,7 +2447,7 @@ public class ServerGamePacketListenerImpl
@@ -1582,7 +_,7 @@
this.lastSeenMessages.applyOffset(packet.offset());
} catch (LastSeenMessagesValidator.ValidationException var5) {
LOGGER.error("Failed to validate message acknowledgement offset from {}: {}", this.player.getName().getString(), var5.getMessage());
@@ -1684,10 +1661,10 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
}
@@ -1572,7 +2455,40 @@ public class ServerGamePacketListenerImpl
@@ -1590,7 +_,40 @@
@Override
public void handleAnimate(ServerboundSwingPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
+ // CraftBukkit start - Raytrace to look for 'rogue armswings'
@@ -1725,9 +1702,9 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.player.swing(packet.getHand());
}
@@ -1580,10 +2496,41 @@ public class ServerGamePacketListenerImpl
@@ -1598,6 +_,32 @@
public void handlePlayerCommand(ServerboundPlayerCommandPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
if (this.player.hasClientLoaded()) {
+ // CraftBukkit start
+ if (this.player.isRemoved()) return;
@@ -1757,17 +1734,8 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+
this.player.resetLastActionTime();
switch (packet.getAction()) {
case PRESS_SHIFT_KEY:
this.player.setShiftKeyDown(true);
+ // Paper start - Add option to make parrots stay
+ if (this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
+ this.player.removeEntitiesOnShoulder();
+ }
+ // Paper end - Add option to make parrots stay
break;
case RELEASE_SHIFT_KEY:
this.player.setShiftKeyDown(false);
@@ -1630,6 +2577,14 @@ public class ServerGamePacketListenerImpl
case START_SPRINTING:
@@ -1642,6 +_,14 @@
}
public void sendPlayerChatMessage(PlayerChatMessage chatMessage, ChatType.Bound boundType) {
@@ -1782,7 +1750,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.send(
new ClientboundPlayerChatPacket(
this.nextChatIndex++,
@@ -1652,9 +2607,11 @@ public class ServerGamePacketListenerImpl
@@ -1664,9 +_,11 @@
}
if (i > 4096) {
@@ -1795,7 +1763,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
public void sendDisguisedChatMessage(Component message, ChatType.Bound boundType) {
@@ -1665,6 +2622,17 @@ public class ServerGamePacketListenerImpl
@@ -1677,6 +_,17 @@
return this.connection.getRemoteAddress();
}
@@ -1813,13 +1781,13 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
public void switchToConfig() {
this.waitingForSwitchToConfig = true;
this.removePlayerFromWorld();
@@ -1680,9 +2648,16 @@ public class ServerGamePacketListenerImpl
@@ -1692,9 +_,16 @@
@Override
public void handleInteract(ServerboundInteractPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
if (this.player.hasClientLoaded()) {
final ServerLevel serverLevel = this.player.serverLevel();
final ServerLevel serverLevel = this.player.level();
final Entity target = packet.getTarget(serverLevel);
+ // Spigot start
+ if (target == this.player && !this.player.isSpectator()) {
@@ -1830,7 +1798,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.player.resetLastActionTime();
this.player.setShiftKeyDown(packet.isUsingSecondaryAction());
if (target != null) {
@@ -1691,16 +2666,58 @@ public class ServerGamePacketListenerImpl
@@ -1703,16 +_,58 @@
}
AABB boundingBox = target.getBoundingBox();
@@ -1894,7 +1862,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
ItemStack itemStack1 = success.wasItemInteraction() ? itemStack : ItemStack.EMPTY;
CriteriaTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(ServerGamePacketListenerImpl.this.player, itemStack1, target);
if (success.swingSource() == InteractionResult.SwingSource.SERVER) {
@@ -1712,13 +2729,13 @@ public class ServerGamePacketListenerImpl
@@ -1724,13 +_,13 @@
@Override
public void onInteraction(InteractionHand hand) {
@@ -1910,7 +1878,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
);
}
@@ -1726,14 +2743,19 @@ public class ServerGamePacketListenerImpl
@@ -1738,14 +_,19 @@
public void onAttack() {
if (!(target instanceof ItemEntity)
&& !(target instanceof ExperienceOrb)
@@ -1932,7 +1900,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
ServerGamePacketListenerImpl.LOGGER
.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString());
}
@@ -1742,6 +2764,27 @@ public class ServerGamePacketListenerImpl
@@ -1754,6 +_,27 @@
);
}
}
@@ -1960,7 +1928,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
@@ -1754,7 +2797,7 @@ public class ServerGamePacketListenerImpl
@@ -1766,7 +_,7 @@
case PERFORM_RESPAWN:
if (this.player.wonGame) {
this.player.wonGame = false;
@@ -1969,7 +1937,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.resetPosition();
CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD);
} else {
@@ -1762,11 +2805,11 @@ public class ServerGamePacketListenerImpl
@@ -1774,11 +_,11 @@
return;
}
@@ -1978,13 +1946,13 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.resetPosition();
if (this.server.isHardcore()) {
- this.player.setGameMode(GameType.SPECTATOR);
- this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.server);
- this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.server);
+ this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper - Expand PlayerGameModeChangeEvent
+ this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.player.serverLevel()); // CraftBukkit - per-world
+ this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.player.serverLevel()); // CraftBukkit - per-world
}
}
break;
@@ -1777,16 +2820,28 @@ public class ServerGamePacketListenerImpl
@@ -1789,16 +_,27 @@
@Override
public void handleContainerClose(ServerboundContainerClosePacket packet) {
@@ -1994,17 +1962,16 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+
+ public void handleContainerClose(ServerboundContainerClosePacket packet, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ // Paper end - Inventory close reason
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+
+ if (this.player.isImmobile()) return; // CraftBukkit
+ CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper
+
this.player.doCloseContainer();
}
@Override
public void handleContainerClick(ServerboundContainerClickPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
- if (this.player.containerMenu.containerId == packet.containerId()) {
@@ -2015,7 +1982,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
this.player.containerMenu.sendAllDataToRemote();
} else if (!this.player.containerMenu.stillValid(this.player)) {
LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu);
@@ -1799,7 +2854,340 @@ public class ServerGamePacketListenerImpl
@@ -1811,7 +_,340 @@
} else {
boolean flag = packet.stateId() != this.player.containerMenu.getStateId();
this.player.containerMenu.suppressRemoteUpdates();
@@ -2357,7 +2324,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
for (Entry<HashedStack> entry : Int2ObjectMaps.fastIterable(packet.changedSlots())) {
this.player.containerMenu.setRemoteSlotUnsafe(entry.getIntKey(), entry.getValue());
@@ -1812,6 +3200,7 @@ public class ServerGamePacketListenerImpl
@@ -1824,6 +_,7 @@
} else {
this.player.containerMenu.broadcastChanges();
}
@@ -2365,7 +2332,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
}
@@ -1819,6 +3208,14 @@ public class ServerGamePacketListenerImpl
@@ -1831,6 +_,14 @@
@Override
public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) {
@@ -2377,10 +2344,10 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ }
+ }
+ // Paper end - auto recipe limit
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
this.player.resetLastActionTime();
if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.containerId()) {
@@ -1835,9 +3232,44 @@ public class ServerGamePacketListenerImpl
@@ -1847,9 +_,44 @@
return;
}
@@ -2419,22 +2386,22 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
+ }
+
RecipeBookMenu.PostPlaceAction postPlaceAction = recipeBookMenu.handlePlacement(
- packet.useMaxItems(), this.player.isCreative(), recipeHolder, this.player.serverLevel(), this.player.getInventory()
+ makeAll, this.player.isCreative(), recipeHolder, this.player.serverLevel(), this.player.getInventory()
- packet.useMaxItems(), this.player.isCreative(), recipeHolder, this.player.level(), this.player.getInventory()
+ makeAll, this.player.isCreative(), recipeHolder, this.player.level(), this.player.getInventory()
);
+ // CraftBukkit end
if (postPlaceAction == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE) {
this.player
.connection
@@ -1853,6 +3285,7 @@ public class ServerGamePacketListenerImpl
this.send(new ClientboundPlaceGhostRecipePacket(this.player.containerMenu.containerId, recipeFromDisplay.display().display()));
}
@@ -1863,6 +_,7 @@
@Override
public void handleContainerButtonClick(ServerboundContainerButtonClickPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) {
if (!this.player.containerMenu.stillValid(this.player)) {
@@ -1862,6 +3295,7 @@ public class ServerGamePacketListenerImpl
@@ -1872,6 +_,7 @@
if (flag) {
this.player.containerMenu.broadcastChanges();
}
@@ -2442,7 +2409,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
}
@@ -1878,10 +3312,48 @@ public class ServerGamePacketListenerImpl
@@ -1888,10 +_,48 @@
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45;
boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize();
@@ -2491,7 +2458,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
} else if (flag && flag2) {
if (this.dropSpamThrottler.isUnderThreshold()) {
this.dropSpamThrottler.increment();
@@ -1895,15 +3367,38 @@ public class ServerGamePacketListenerImpl
@@ -1905,15 +_,38 @@
@Override
public void handleSignUpdate(ServerboundSignUpdatePacket packet) {
@@ -2515,7 +2482,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
private void updateSignText(ServerboundSignUpdatePacket packet, List<FilteredText> filteredText) {
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
ServerLevel serverLevel = this.player.serverLevel();
ServerLevel serverLevel = this.player.level();
BlockPos pos = packet.getPos();
if (serverLevel.hasChunkAt(pos)) {
+ // Paper start - Add API for client-side signs
@@ -2531,10 +2498,10 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
if (!(serverLevel.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity)) {
return;
}
@@ -1915,14 +3410,32 @@ public class ServerGamePacketListenerImpl
@@ -1925,14 +_,32 @@
@Override
public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
- this.player.getAbilities().flying = packet.isFlying() && this.player.getAbilities().mayfly;
+ // CraftBukkit start
+ if (this.player.getAbilities().mayfly && this.player.getAbilities().flying != packet.isFlying()) {
@@ -2551,7 +2518,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
@Override
public void handleClientInformation(ServerboundClientInformationPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ // Paper start - do not accept invalid information
+ if (packet.information().viewDistance() < 0) {
+ LOGGER.warn("Disconnecting {} for invalid view distance: {}", this.player.getScoreboardName(), packet.information().viewDistance());
@@ -2565,16 +2532,16 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
if (this.player.isModelPartShown(PlayerModelPart.HAT) != isModelPartShown) {
this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player));
}
@@ -1932,7 +3445,7 @@ public class ServerGamePacketListenerImpl
public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) {
- this.server.setDifficulty(packet.getDifficulty(), false);
@@ -1948,7 +_,7 @@
packet.difficulty().getDisplayName()
);
} else {
- this.server.setDifficulty(packet.difficulty(), false);
+ // this.server.setDifficulty(packet.getDifficulty(), false); // Paper - per level difficulty; don't allow clients to change this
}
}
@@ -1952,7 +3465,7 @@ public class ServerGamePacketListenerImpl
@@ -1982,7 +_,7 @@
ProfilePublicKey.Data data2 = data.profilePublicKey();
if (!Objects.equals(data1, data2)) {
if (data1 != null && data2.expiresAt().isBefore(data1.expiresAt())) {
@@ -2583,7 +2550,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
} else {
try {
SignatureValidator profileKeySignatureValidator = this.server.getProfileKeySignatureValidator();
@@ -1963,8 +3476,8 @@ public class ServerGamePacketListenerImpl
@@ -1993,8 +_,8 @@
this.resetPlayerChatState(data.validate(this.player.getGameProfile(), profileKeySignatureValidator));
} catch (ProfilePublicKey.ValidationException var6) {
@@ -2594,7 +2561,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
}
}
}
@@ -1978,7 +3491,7 @@ public class ServerGamePacketListenerImpl
@@ -2008,7 +_,7 @@
this.connection
.setupInboundProtocol(
ConfigurationProtocols.SERVERBOUND,
@@ -2603,7 +2570,7 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
);
}
}
@@ -1997,27 +3510,32 @@ public class ServerGamePacketListenerImpl
@@ -2027,27 +_,32 @@
private void resetPlayerChatState(RemoteChatSession chatSession) {
this.chatSession = chatSession;
@@ -2632,12 +2599,12 @@ index 94c5293981cb33fdc029ba4c80284d3b538e9699..f636efc5b31c996cb083b47877c58bc7
@Override
public void handleClientTickEnd(ServerboundClientTickEndPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ this.tickEndEvent.callEvent(); // Paper - add client tick end event
if (!this.receivedMovementThisTick) {
this.player.setKnownMovement(Vec3.ZERO);
}
@@ -2048,4 +3566,17 @@ public class ServerGamePacketListenerImpl
@@ -2078,4 +_,17 @@
interface EntityInteraction {
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
}

View File

@@ -1,14 +1,6 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
index 22d8ebffcd347051a917fcc2c994c38ddb713622..0ae31252b2e2d82bfa883abc8fb78d550ecf4849 100644
--- a/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
@@ -14,9 +14,20 @@ import net.minecraft.server.MinecraftServer;
@@ -14,9 +_,20 @@
public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketListener {
private static final Component IGNORE_STATUS_REASON = Component.translatable("disconnect.ignoring_status_request");
@@ -29,7 +21,7 @@ index 22d8ebffcd347051a917fcc2c994c38ddb713622..0ae31252b2e2d82bfa883abc8fb78d55
public ServerHandshakePacketListenerImpl(MinecraftServer server, Connection connection) {
this.server = server;
this.connection = connection;
@@ -24,6 +35,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
@@ -24,6 +_,7 @@
@Override
public void handleIntention(ClientIntentionPacket packet) {
@@ -37,7 +29,7 @@ index 22d8ebffcd347051a917fcc2c994c38ddb713622..0ae31252b2e2d82bfa883abc8fb78d55
switch (packet.intention()) {
case LOGIN:
this.beginLogin(packet, false);
@@ -50,22 +62,118 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
@@ -50,22 +_,118 @@
default:
throw new UnsupportedOperationException("Invalid intention " + packet.intention());
}
@@ -81,16 +73,16 @@ index 22d8ebffcd347051a917fcc2c994c38ddb713622..0ae31252b2e2d82bfa883abc8fb78d55
+ org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t);
+ }
+ // Paper end - Connection throttle
if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) {
if (packet.protocolVersion() != SharedConstants.getCurrentVersion().protocolVersion()) {
- Component component;
- if (packet.protocolVersion() < 754) {
- component = Component.translatable("multiplayer.disconnect.outdated_client", SharedConstants.getCurrentVersion().getName());
- component = Component.translatable("multiplayer.disconnect.outdated_client", SharedConstants.getCurrentVersion().name());
+ net.kyori.adventure.text.Component adventureComponent; // Paper - Fix hex colors not working in some kick messages
+ if (packet.protocolVersion() < SharedConstants.getCurrentVersion().getProtocolVersion()) { // Spigot - SPIGOT-7546: Handle version check correctly for outdated client message
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); // Spigot // Paper - Fix hex colors not working in some kick messages
+ if (packet.protocolVersion() < SharedConstants.getCurrentVersion().protocolVersion()) { // Spigot - SPIGOT-7546: Handle version check correctly for outdated client message
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().name())); // Spigot // Paper - Fix hex colors not working in some kick messages
} else {
- component = Component.translatable("multiplayer.disconnect.incompatible", SharedConstants.getCurrentVersion().getName());
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); // Spigot // Paper - Fix hex colors not working in some kick messages
- component = Component.translatable("multiplayer.disconnect.incompatible", SharedConstants.getCurrentVersion().name());
+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().name())); // Spigot // Paper - Fix hex colors not working in some kick messages
}
+ Component component = io.papermc.paper.adventure.PaperAdventure.asVanilla(adventureComponent); // Paper - Fix hex colors not working in some kick messages

View File

@@ -1036,7 +1036,7 @@
+ // Paper start - PlayerLeashEvent
+ final org.bukkit.event.entity.PlayerLeashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(
+ leashable1,
+ (Leashable) this,
+ this,
+ player,
+ hand
+ );

View File

@@ -1,22 +1,13 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d452d517e1 100644
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -88,9 +88,17 @@ public class ArmorStand extends LivingEntity {
public Rotations rightArmPose = DEFAULT_RIGHT_ARM_POSE;
public Rotations leftLegPose = DEFAULT_LEFT_LEG_POSE;
public Rotations rightLegPose = DEFAULT_RIGHT_LEG_POSE;
@@ -85,9 +_,16 @@
private boolean invisible = false;
public long lastHit;
public int disabledSlots = 0;
+ public boolean canMove = true; // Paper
+ // Paper start - Allow ArmorStands not to tick
+ public boolean canTick = true;
+ public boolean canTickSetByAPI = false;
+ private boolean noTickPoseDirty = false;
+ private boolean noTickEquipmentDirty = false;
+ // Paper end - Allow ArmorStands not to tick
@@ -26,7 +17,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
}
public ArmorStand(Level level, double x, double y, double z) {
@@ -102,6 +110,13 @@ public class ArmorStand extends LivingEntity {
@@ -99,6 +_,13 @@
return createLivingAttributes().add(Attributes.STEP_HEIGHT, 0.0);
}
@@ -40,7 +31,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
@Override
public void refreshDimensions() {
double x = this.getX();
@@ -137,6 +152,14 @@ public class ArmorStand extends LivingEntity {
@@ -134,6 +_,14 @@
return slot != EquipmentSlot.BODY && slot != EquipmentSlot.SADDLE && !this.isDisabled(slot);
}
@@ -53,39 +44,35 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
+ // Paper - Allow ArmorStands not to tick; Still update equipment
+
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
@@ -150,6 +173,7 @@ public class ArmorStand extends LivingEntity {
protected void addAdditionalSaveData(ValueOutput output) {
super.addAdditionalSaveData(output);
@@ -147,6 +_,7 @@
}
compound.put("Pose", this.writePose());
+ if (this.canTickSetByAPI) compound.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick
output.store("Pose", ArmorStand.ArmorStandPose.CODEC, this.getArmorStandPose());
+ if (this.canTickSetByAPI) output.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick
}
@Override
@@ -163,6 +187,12 @@ public class ArmorStand extends LivingEntity {
this.setMarker(compound.getBooleanOr("Marker", false));
@@ -160,10 +_,16 @@
this.setMarker(input.getBooleanOr("Marker", false));
this.noPhysics = !this.hasPhysics();
this.readPose(compound.getCompoundOrEmpty("Pose"));
input.read("Pose", ArmorStand.ArmorStandPose.CODEC).ifPresent(this::setArmorStandPose);
+ // Paper start - Allow ArmorStands not to tick
+ compound.getBoolean("Paper.CanTickOverride").ifPresent(canTick -> {
+ this.canTick = canTick;
+ if (input.getInt("Paper.CanTickOverride").isPresent()) { // Check if is set
+ this.canTick = input.getBooleanOr("Paper.CanTickOverride", true);
+ this.canTickSetByAPI = true;
+ });
+ }
+ // Paper end - Allow ArmorStands not to tick
}
private void readPose(CompoundTag compound) {
@@ -204,7 +234,7 @@ public class ArmorStand extends LivingEntity {
}
@Override
- public boolean isPushable() {
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
return false;
}
@@ -214,6 +244,7 @@ public class ArmorStand extends LivingEntity {
@@ -173,6 +_,7 @@
@Override
protected void pushEntities() {
@@ -93,7 +80,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
for (Entity entity : this.level().getEntities(this, this.getBoundingBox(), RIDABLE_MINECARTS)) {
if (this.distanceToSqr(entity) <= 0.2) {
entity.push(this);
@@ -286,7 +317,25 @@ public class ArmorStand extends LivingEntity {
@@ -245,7 +_,25 @@
return false;
} else if (itemBySlot.isEmpty() && (this.disabledSlots & 1 << slot.getFilterBit(16)) != 0) {
return false;
@@ -120,7 +107,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
this.setItemSlot(slot, stack.copyWithCount(1));
return true;
} else if (stack.isEmpty() || stack.getCount() <= 1) {
@@ -299,6 +348,7 @@ public class ArmorStand extends LivingEntity {
@@ -258,6 +_,7 @@
this.setItemSlot(slot, stack.split(1));
return true;
}
@@ -128,7 +115,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
}
@Override
@@ -308,15 +358,32 @@ public class ArmorStand extends LivingEntity {
@@ -267,15 +_,32 @@
} else if (!level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && damageSource.getEntity() instanceof Mob) {
return false;
} else if (damageSource.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
@@ -165,7 +152,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
if (this.isOnFire()) {
this.causeDamage(level, damageSource, 0.15F);
} else {
@@ -325,9 +392,19 @@ public class ArmorStand extends LivingEntity {
@@ -284,9 +_,19 @@
return false;
} else if (damageSource.is(DamageTypeTags.BURNS_ARMOR_STANDS) && this.getHealth() > 0.5F) {
@@ -185,7 +172,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
boolean isCanBreakArmorStand = damageSource.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND);
boolean isAlwaysKillsArmorStands = damageSource.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS);
if (!isCanBreakArmorStand && !isAlwaysKillsArmorStands) {
@@ -337,7 +414,7 @@ public class ArmorStand extends LivingEntity {
@@ -296,7 +_,7 @@
} else if (damageSource.isCreativePlayer()) {
this.playBrokenSound();
this.showBreakingParticles();
@@ -194,7 +181,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
return true;
} else {
long gameTime = level.getGameTime();
@@ -346,9 +423,9 @@ public class ArmorStand extends LivingEntity {
@@ -305,9 +_,9 @@
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
this.lastHit = gameTime;
} else {
@@ -206,7 +193,7 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
}
return true;
@@ -400,31 +477,42 @@ public class ArmorStand extends LivingEntity {
@@ -359,31 +_,42 @@
float health = this.getHealth();
health -= damageAmount;
if (health <= 0.5F) {
@@ -243,6 +230,8 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
+ ItemStack itemStack = this.equipment.get(equipmentSlot); // Paper - move equipment removal past event call
if (!itemStack.isEmpty()) {
- Block.popResource(this.level(), this.blockPosition().above(), itemStack);
- }
- }
+ this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly}
+ }
+ }
@@ -251,24 +240,21 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
+ if (!event.isCancelled()) {
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
+ this.equipment.set(equipmentSlot, ItemStack.EMPTY);
}
}
+ }
+ }
+ return event;
+ // Paper end - move equipment removal past event call
}
private void playBrokenSound() {
@@ -458,7 +546,28 @@ public class ArmorStand extends LivingEntity {
@@ -431,9 +_,40 @@
return this.isSmall();
}
@Override
public void tick() {
+ // Paper start - Allow ArmorStands not to tick
+ // Paper start - Allow ArmorStands not to tick
+ @Override
+ public void tick() {
+ if (!this.canTick) {
+ if (this.noTickPoseDirty) {
+ this.noTickPoseDirty = false;
+ this.updatePose();
+ }
+
+ if (this.noTickEquipmentDirty) {
+ this.noTickEquipmentDirty = false;
+ this.detectEquipmentUpdates();
@@ -276,27 +262,9 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
+
+ return;
+ }
+ // Paper end - Allow ArmorStands not to tick
super.tick();
+ // Paper start - Allow ArmorStands not to tick
+ this.updatePose();
+ super.tick();
+ }
+
+ public void updatePose() {
+ // Paper end - Allow ArmorStands not to tick
Rotations rotations = this.entityData.get(DATA_HEAD_POSE);
if (!this.headPose.equals(rotations)) {
this.setHeadPose(rotations);
@@ -506,9 +615,32 @@ public class ArmorStand extends LivingEntity {
return this.isSmall();
}
+ // CraftBukkit start
+ @Override
+ public boolean shouldDropExperience() {
+ return true; // MC-157395, SPIGOT-5193 even small armor stands should drop
+ }
+ // CraftBukkit end
+ // Paper end - Allow ArmorStands not to tick
+
@Override
public void kill(ServerLevel level) {
@@ -321,47 +289,9 @@ index 30e2d529bb98748fcd2caab997fd8f6bbed49e3f..f5ce8151bb1bae9be638ced7f74899d4
this.gameEvent(GameEvent.ENTITY_DIE);
}
@@ -572,31 +704,37 @@ public class ArmorStand extends LivingEntity {
public void setHeadPose(Rotations headPose) {
this.headPose = headPose;
this.entityData.set(DATA_HEAD_POSE, headPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setBodyPose(Rotations bodyPose) {
this.bodyPose = bodyPose;
this.entityData.set(DATA_BODY_POSE, bodyPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftArmPose(Rotations leftArmPose) {
this.leftArmPose = leftArmPose;
this.entityData.set(DATA_LEFT_ARM_POSE, leftArmPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setRightArmPose(Rotations rightArmPose) {
this.rightArmPose = rightArmPose;
this.entityData.set(DATA_RIGHT_ARM_POSE, rightArmPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftLegPose(Rotations leftLegPose) {
this.leftLegPose = leftLegPose;
this.entityData.set(DATA_LEFT_LEG_POSE, leftLegPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setRightLegPose(Rotations rightLegPose) {
this.rightLegPose = rightLegPose;
this.entityData.set(DATA_RIGHT_LEG_POSE, rightLegPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public Rotations getHeadPose() {
@@ -728,4 +866,13 @@ public class ArmorStand extends LivingEntity {
public boolean canBeSeenByAnyone() {
return !this.isInvisible() && !this.isMarker();
@@ -684,4 +_,13 @@
.apply(instance, ArmorStand.ArmorStandPose::new)
);
}
+
+ // Paper start

View File

@@ -0,0 +1,29 @@
--- a/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
+++ b/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
@@ -82,7 +_,7 @@
boolean flag = false;
for (Leashable leashable : Leashable.leashableLeashedTo(player)) {
- if (leashable.canHaveALeashAttachedTo(this)) {
+ if (leashable.canHaveALeashAttachedTo(this) && org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerLeashEntityEvent(leashable, this, player, hand)) { // Paper - leash event
leashable.setLeashedTo(this, true);
flag = true;
}
@@ -91,7 +_,7 @@
boolean flag1 = false;
if (!flag && !player.isSecondaryUseActive()) {
for (Leashable leashable1 : Leashable.leashableLeashedTo(this)) {
- if (leashable1.canHaveALeashAttachedTo(player)) {
+ if (leashable1.canHaveALeashAttachedTo(player) && org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerLeashEntityEvent(leashable1, player, player, hand)) { // Paper - leash event
leashable1.setLeashedTo(player, true);
flag1 = true;
}
@@ -111,7 +_,7 @@
@Override
public void notifyLeasheeRemoved(Leashable leashHolder) {
if (Leashable.leashableLeashedTo(this).isEmpty()) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
}
}

View File

@@ -0,0 +1,38 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
@@ -214,7 +_,14 @@
nextSpawnData.getEquipment().ifPresent(mob::equip);
}
- if (!level.tryAddFreshEntityWithPassengers(entity)) {
+ // Paper start - TrialSpawnerSpawnEvent + SpawnReason
+ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ return Optional.empty();
+ }
+ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) {
+ // Paper end - TrialSpawnerSpawnEvent + SpawnReason
return Optional.empty();
}
@@ -233,6 +_,19 @@
LootParams lootParams = new LootParams.Builder(level).create(LootContextParamSets.EMPTY);
ObjectArrayList<ItemStack> randomItems = lootTable1.getRandomItems(lootParams);
if (!randomItems.isEmpty()) {
+ // CraftBukkit start
+ org.bukkit.event.block.BlockDispenseLootEvent spawnerDispenseLootEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDispenseLootEvent(
+ level,
+ pos,
+ null,
+ randomItems
+ );
+ if (spawnerDispenseLootEvent.isCancelled()) {
+ return;
+ }
+
+ randomItems = new ObjectArrayList<>(spawnerDispenseLootEvent.getDispensedLoot().stream().map(org.bukkit.craftbukkit.inventory.CraftItemStack::asNMSCopy).toList());
+ // CraftBukkit end
for (ItemStack itemStack : randomItems) {
DefaultDispenseItemBehavior.spawnItem(level, itemStack, 2, Direction.UP, Vec3.atBottomCenterOf(pos).relative(Direction.UP, 1.2));
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java
@@ -185,7 +_,7 @@
mob.dropPreservedEquipment(level);
}
- entity.remove(Entity.RemovalReason.DISCARDED);
+ entity.remove(Entity.RemovalReason.DISCARDED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - Add bukkit remove cause;
}
});
if (!spawner.ominousConfig().spawnPotentialsDefinition().isEmpty()) {

View File

@@ -1510,9 +1510,14 @@ public class CraftEventFactory {
return true;
}
public static @Nullable PlayerLeashEntityEvent callPlayerLeashEntityEvent(Leashable leashed, Leashable leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
if (!(leashed instanceof final Entity leashedEntity) || !(leashHolder instanceof final Entity leasheHolderEntity)) return null;
return callPlayerLeashEntityEvent(leashedEntity, leasheHolderEntity, player, hand);
public static boolean handlePlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
if (!(leashed instanceof final Entity leashedEntity)) return false;
return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand).callEvent();
}
public static @Nullable PlayerLeashEntityEvent callPlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
if (!(leashed instanceof final Entity leashedEntity)) return null;
return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand);
}
public static PlayerLeashEntityEvent callPlayerLeashEntityEvent(Entity entity, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {