Compare commits

...
Author SHA1 Message Date
Owen1212055 7f778ba634 PlayerMoveVehicleEvent 2025-03-03 12:07:30 -05:00
Owen1212055 2c7b5c8036 Reworked Vehicle PlayerMoveEvent Handling 2025-03-03 11:46:49 -05:00
Warrior 1d5e5a57e9 Document replacement for Skull owner profile methods (#12195) 2025-02-28 20:51:39 +01:00
Warrior b506626824 Remove unused light queue size option (#12201) 2025-02-28 17:58:45 +01:00
okx-code 0a6e7435b3 Fix invulnerability damage and armour (#12190) 2025-02-26 14:06:42 +01:00
Jake Potrebic 9421f22372 Make CustomArgumentType use parse(reader,source) (#12191) 2025-02-26 13:12:23 +01:00
Warrior f63dbeafde Fix cancelled HangingPlaceEvent inventory desync (#12161) 2025-02-25 22:33:35 +01:00
Pedro fc56c728c0 Add methods for Creaking (#12094) 2025-02-25 22:23:47 +01:00
Lulu13022002 9b9f046f41 Remove broken code (#12171) 2025-02-25 22:14:21 +01:00
_Novit_ 7f3d3591de Use MiniMessage#deserialize(String, Pointered) in sendRichMessage for send messages (#12177) 2025-02-25 22:06:20 +01:00
Warrior a501c45918 Deprecate server config getters (#12189) 2025-02-25 22:03:38 +01:00
Warrior ca2610904b Don't process empty rcon commands (#12188) 2025-02-25 22:03:14 +01:00
Glicz b00875f86d Add a method on Registry to get the size (#12182) 2025-02-25 22:02:48 +01:00
Warrior 5f2ee83ed4 Fix first execution of async delayed/repeating tasks being sync (#12166) 2025-02-25 21:45:33 +01:00
Warrior 1d9b399427 Add config option for failed beehive release cooldowns (#12186) 2025-02-25 21:45:18 +01:00
Nassim Jahnke f12d33f04e Track codec writing 2025-02-25 21:45:02 +01:00
Bjarne Koll 9be4e07a3e Pin snapshot dependencies (#12185)
Additionally pins configurate-core as a transitive dependency of
configurate-yml, as the yaml snapshot depends on a snapshot itself.
2025-02-25 21:44:42 +01:00
36 changed files with 527 additions and 203 deletions

No files matched your search

+1
View File
@@ -227,6 +227,7 @@ public net.minecraft.world.entity.LivingEntity detectEquipmentUpdates()V
public net.minecraft.world.entity.LivingEntity effectsDirty
public net.minecraft.world.entity.LivingEntity entityEventForEquipmentBreak(Lnet/minecraft/world/entity/EquipmentSlot;)B
public net.minecraft.world.entity.LivingEntity getDeathSound()Lnet/minecraft/sounds/SoundEvent;
public net.minecraft.world.entity.LivingEntity getRiddenSpeed(Lnet/minecraft/world/entity/player/Player;)F
public net.minecraft.world.entity.LivingEntity getSoundVolume()F
public net.minecraft.world.entity.LivingEntity jumping
public net.minecraft.world.entity.LivingEntity lastHurt
@@ -0,0 +1,81 @@
package io.papermc.paper.event.player;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Runs when a player attempts to move a vehicle to a new position.
*/
@NullMarked
public class PlayerMoveVehicleEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Location from;
private final Location to;
private final Entity vehicle;
private boolean cancelled;
@ApiStatus.Internal
public PlayerMoveVehicleEvent(final Player player, final Entity vehicle, final Location from, final Location to) {
super(player);
this.vehicle = vehicle;
this.from = from;
this.to = to;
}
/**
* Gets the location the vehicle moved from
*
* @return Location the vehicle moved from
*/
public Location getFrom() {
return this.from.clone();
}
/**
* Gets the location the vehicle is moving to
*
* @return Location the vehicle is moving to
*/
public Location getTo() {
return this.to.clone();
}
/**
* Gets the vehicle this player is currently moving.
* Note: You should use {@link PlayerMoveVehicleEvent#getTo()} for getting the previous and
* new location of the vehicle.
* <p>
* The behavior of getting the location of the vehicle in this event is undefined.
*
* @return vehicle
*/
public Entity getVehicle() {
return vehicle;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
}
@@ -2980,8 +2980,19 @@ public final class Bukkit {
}
// Paper end - Folia region threading API
/**
* @deprecated All methods on this class have been deprecated, see the individual methods for replacements.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
@NotNull
public static Server.Spigot spigot() {
return server.spigot();
}
/**
* Restarts the server. If the server administrator has not configured restarting, the server will stop.
*/
public static void restart() {
server.restart();
}
}
@@ -3,6 +3,7 @@ package org.bukkit;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
@@ -297,6 +298,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
return MemoryKey.values().iterator();
}
@Override
public int size() {
return MemoryKey.values().size();
}
@Override
public @Nullable MemoryKey get(final NamespacedKey key) {
return MemoryKey.getByKey(key);
@@ -536,6 +542,13 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
return (namespacedKey != null) ? this.get(namespacedKey) : null;
}
/**
* Gets the size of the registry.
*
* @return the size of the registry
*/
int size();
@ApiStatus.Internal
class SimpleRegistry<T extends Enum<T> & Keyed> extends NotARegistry<T> { // Paper - remove final
@@ -564,6 +577,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
return this.map.get(key);
}
@Override
public int size() {
return map.size();
}
@Override
public Iterator<T> iterator() {
return this.map.values().iterator();
@@ -584,6 +602,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
return StreamSupport.stream(this.spliterator(), false);
}
@Override
public int size() {
return Iterables.size(this);
}
@Override
public NamespacedKey getKey(final A value) {
return value.getKey();
+42 -2
View File
@@ -422,7 +422,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @param message MiniMessage content
*/
default void sendRichMessage(final @NotNull String message) {
this.sendMessage(MiniMessage.miniMessage().deserialize(message));
this.sendMessage(MiniMessage.miniMessage().deserialize(message, this));
}
/**
@@ -435,7 +435,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @param resolvers resolvers to use
*/
default void sendRichMessage(final @NotNull String message, final @NotNull TagResolver... resolvers) {
this.sendMessage(MiniMessage.miniMessage().deserialize(message, resolvers));
this.sendMessage(MiniMessage.miniMessage().deserialize(message, this, resolvers));
}
/**
@@ -2309,24 +2309,52 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
// Spigot start
public class Spigot {
/**
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @return The server's spigot config.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
@NotNull
public org.bukkit.configuration.file.YamlConfiguration getConfig() {
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @return The server's bukkit config.
*/
// Paper start
@Deprecated(since = "1.21.4", forRemoval = true)
@NotNull
public org.bukkit.configuration.file.YamlConfiguration getBukkitConfig()
{
throw new UnsupportedOperationException( "Not supported yet." );
}
/**
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @return The server's spigot config.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
@NotNull
public org.bukkit.configuration.file.YamlConfiguration getSpigotConfig()
{
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @return The server's paper config.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
@NotNull
public org.bukkit.configuration.file.YamlConfiguration getPaperConfig()
{
@@ -2358,16 +2386,28 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
/**
* Restart the server. If the server administrator has not configured restarting, the server will stop.
*
* @deprecated Use {@link Server#restart()} instead.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
public void restart() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
/**
* @deprecated All methods on this class have been deprecated, see the individual methods for replacements.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
@NotNull
Spigot spigot();
// Spigot end
/**
* Restarts the server. If the server administrator has not configured restarting, the server will stop.
*/
void restart();
void reloadPermissions(); // Paper
boolean reloadCommandAliases(); // Paper
@@ -82,6 +82,8 @@ public interface Skull extends TileState {
* may appear as the texture depending on skull type.
*
* @return the profile of the owning player
*
* @deprecated Use {@link #getPlayerProfile()} instead.
*/
@Nullable
@Deprecated // Paper
@@ -98,6 +100,8 @@ public interface Skull extends TileState {
* @param profile the profile of the owning player
* @throws IllegalArgumentException if the profile does not contain the
* necessary information
*
* @deprecated Use {@link #setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile)} instead.
*/
@Deprecated // Paper
void setOwnerProfile(@Nullable PlayerProfile profile);
@@ -147,7 +147,7 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe
* @param message MiniMessage content
*/
default void sendRichMessage(final @NotNull String message) {
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message));
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, this));
}
/**
@@ -160,7 +160,7 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe
* @param resolvers resolvers to use
*/
default void sendRichMessage(final @NotNull String message, final net.kyori.adventure.text.minimessage.tag.resolver.@NotNull TagResolver... resolvers) {
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, resolvers));
this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, this, resolvers));
}
/**
@@ -1,8 +1,43 @@
package org.bukkit.entity;
import org.bukkit.Location;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Represents a Creaking.
*/
@NullMarked
public interface Creaking extends Monster {
/**
* Gets the home location for this creaking (where its {@link org.bukkit.block.CreakingHeart} could be found).
*
* @return the location of the home if available, null otherwise
*/
@Nullable
Location getHome();
/**
* Activates this creaking to target and follow a player.
*
* @param player the target
*/
void activate(final Player player);
/**
* Deactivates the creaking, clearing its current attack target and
* marking it as inactive.
*/
void deactivate();
/**
* Returns if this creaking is currently active and hunting.
*
* @see #activate(Player)
*
* @return true if active
*/
boolean isActive();
}
+4 -3
View File
@@ -137,13 +137,14 @@ dependencies {
runtimeOnly(log4jPlugins.output)
alsoShade(log4jPlugins.output)
implementation("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT") {
implementation("com.velocitypowered:velocity-native:3.4.0-20250222.161222-36") {
isTransitive = false
}
implementation("io.netty:netty-codec-haproxy:4.1.115.Final") // Add support for proxy protocol
implementation("org.apache.logging.log4j:log4j-iostreams:2.24.1")
implementation("org.ow2.asm:asm-commons:9.7.1")
implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT")
implementation("org.spongepowered:configurate-yaml:4.2.0-20250225.064233-199")
implementation("org.spongepowered:configurate-core:4.2.0-20250225.064233-204") // Pinned dependency of above pinned yaml snapshot.
implementation("commons-lang:commons-lang:2.6")
runtimeOnly("org.xerial:sqlite-jdbc:3.47.0.0")
runtimeOnly("com.mysql:mysql-connector-j:9.1.0")
@@ -173,7 +174,7 @@ dependencies {
// Spark
implementation("me.lucko:spark-api:0.1-20240720.200737-2")
implementation("me.lucko:spark-paper:1.10.119-SNAPSHOT")
implementation("me.lucko:spark-paper:1.10.119-20241121.092015-1")
}
tasks.jar {
@@ -366,7 +366,7 @@ index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f
import org.slf4j.Logger;
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 8204528c26456929fdec0d8ba7a5a52128409097..01bc2d1639be9f04afc63e5841c5c99730ea37d8 100644
index cdb4d313eb33c049c8467fe5d31fb0d671737768..40b799fd90b0db13bdaa8834c021f5ca8f25ce10 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -476,7 +476,7 @@ index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf
public void tick() {
super.tick();
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index b15420ffa1432d49aec8e91e917598bde4e94337..054ece1d539d69a4b7eec57e681179343c7e75c3 100644
index 54cf80831372d102e8d2966ac104678caebdf336..d89c3949e16ff6cb0374da29ec6731d854b5f105 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -381,6 +381,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -533,10 +533,10 @@ index b15420ffa1432d49aec8e91e917598bde4e94337..054ece1d539d69a4b7eec57e68117934
movement = this.maybeBackOffFromEdge(movement, type);
Vec3 vec3 = this.collide(movement);
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index ff513e8c87bf42be756e46f4dbfec8dda2b8cb60..239c443ddc9bacc08a39a8ef2ab17016a2480549 100644
index bf5fd2a6c8630ea2bb06881d4d365dda9a4e90ea..4713c29cc2add476f568163a29cb297f5d1049df 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -3096,6 +3096,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3103,6 +3103,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
return false;
}
@@ -6,10 +6,10 @@ Subject: [PATCH] Optimise collision checking in player move packet handling
Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d149849983107c539b31 100644
index 2e838877ce1da44c0dbe2c3275a76fc97e640fa3..2389fbf02ca593829f91185ffa6c790c0d6ebb12 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -561,7 +561,7 @@ public class ServerGamePacketListenerImpl
@@ -554,7 +554,7 @@ public class ServerGamePacketListenerImpl
return;
}
@@ -18,7 +18,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
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
@@ -571,6 +571,7 @@ public class ServerGamePacketListenerImpl
@@ -564,6 +564,7 @@ public class ServerGamePacketListenerImpl
}
rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
@@ -26,7 +26,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
double verticalDelta = d4; // Paper - Decompile fix, was named d11 previously, is now gone in the source
d3 = d - rootVehicle.getX();
d4 = d1 - rootVehicle.getY();
@@ -582,14 +583,22 @@ public class ServerGamePacketListenerImpl
@@ -575,15 +576,20 @@ public class ServerGamePacketListenerImpl
d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false;
if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
@@ -36,23 +36,21 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
}
rootVehicle.absMoveTo(d, d1, d2, f, f1);
this.player.absMoveTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
- boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
- if (flag && (flag2 || !flag3)) {
+ // Paper start - optimise out extra getCubes
// Paper start
- boolean teleportBack = flag && (flag2 || !flag3);
+ boolean teleportBack = flag2; // violating this is always a fail
+ if (!teleportBack) {
if (!teleportBack) {
+ // note: only call after setLocation, or else getBoundingBox is wrong
+ AABB newBox = rootVehicle.getBoundingBox();
+ if (didCollide || !oldBox.equals(newBox)) {
+ teleportBack = this.hasNewCollision(serverLevel, rootVehicle, oldBox, newBox);
+ } // else: no collision at all detected, why do we care?
+ }
+ if (teleportBack) { // Paper end - optimise out extra getCubes
rootVehicle.absMoveTo(x, y, z, f, f1);
this.player.absMoveTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
@@ -667,9 +676,32 @@ public class ServerGamePacketListenerImpl
+
// Move event - emulating from the vehicle
org.bukkit.entity.Entity rootVehicleBukkit = rootVehicle.getBukkitEntity();
Location from = new Location(rootVehicleBukkit.getWorld(), x, y, z, f, f1); // Copy from #absMoveTo on teleportBack
@@ -637,9 +643,32 @@ public class ServerGamePacketListenerImpl
}
private boolean noBlocksAround(Entity entity) {
@@ -88,7 +86,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
}
@Override
@@ -1368,7 +1400,7 @@ public class ServerGamePacketListenerImpl
@@ -1338,7 +1367,7 @@ public class ServerGamePacketListenerImpl
}
}
@@ -97,7 +95,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
@@ -1407,6 +1439,7 @@ public class ServerGamePacketListenerImpl
@@ -1377,6 +1406,7 @@ public class ServerGamePacketListenerImpl
boolean flag1 = this.player.verticalCollisionBelow;
this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
@@ -105,7 +103,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
// Paper start - prevent position desync
if (this.awaitingPositionFromClient != null) {
return; // ... thanks Mojang for letting move calls teleport across dimensions.
@@ -1439,7 +1472,17 @@ public class ServerGamePacketListenerImpl
@@ -1409,7 +1439,17 @@ public class ServerGamePacketListenerImpl
}
// Paper start - Add fail move event
@@ -124,7 +122,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
if (teleportBack) {
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
toX, toY, toZ, toYaw, toPitch, false);
@@ -1575,7 +1618,7 @@ public class ServerGamePacketListenerImpl
@@ -1545,7 +1585,7 @@ public class ServerGamePacketListenerImpl
private boolean updateAwaitingTeleport() {
if (this.awaitingPositionFromClient != null) {
@@ -133,7 +131,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
this.awaitingTeleportTime = this.tickCount;
this.teleport(
this.awaitingPositionFromClient.x,
@@ -1594,6 +1637,33 @@ public class ServerGamePacketListenerImpl
@@ -1564,6 +1604,33 @@ public class ServerGamePacketListenerImpl
}
}
@@ -11,11 +11,11 @@ a portal in spectator mode and then later switching to creative mode
would portal the player.
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 366c26b2ca539be189b67d75ae73a587c4102c14..4068132a33f87dd07d6df1033ed11ba16a57313b 100644
index 2389fbf02ca593829f91185ffa6c790c0d6ebb12..ae2ca486db1e689862fc446dc1d051fb058a1187 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -657,7 +657,7 @@ public class ServerGamePacketListenerImpl
// CraftBukkit end
@@ -624,7 +624,7 @@ public class ServerGamePacketListenerImpl
}
this.player.serverLevel().getChunkSource().move(this.player);
- rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position());
@@ -23,7 +23,7 @@ index 366c26b2ca539be189b67d75ae73a587c4102c14..4068132a33f87dd07d6df1033ed11ba1
Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z);
this.handlePlayerKnownMovement(vec3);
rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3);
@@ -1574,7 +1574,7 @@ public class ServerGamePacketListenerImpl
@@ -1541,7 +1541,7 @@ public class ServerGamePacketListenerImpl
Vec3 vec3 = new Vec3(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z);
this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3);
this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround());
@@ -1,6 +1,6 @@
--- a/net/minecraft/network/FriendlyByteBuf.java
+++ b/net/minecraft/network/FriendlyByteBuf.java
@@ -70,6 +_,7 @@
@@ -70,14 +_,20 @@
public class FriendlyByteBuf extends ByteBuf {
public static final int DEFAULT_NBT_QUOTA = 2097152;
private final ByteBuf source;
@@ -8,8 +8,13 @@
public static final short MAX_STRING_LENGTH = 32767;
public static final int MAX_COMPONENT_STRING_LENGTH = 262144;
private static final int PUBLIC_KEY_SIZE = 256;
@@ -78,6 +_,7 @@
private static final int MAX_PUBLIC_KEY_HEADER_SIZE = 256;
private static final int MAX_PUBLIC_KEY_LENGTH = 512;
private static final Gson GSON = new Gson();
+ // Paper start - Track codec depth
+ public boolean trackCodecDepth;
+ public byte codecDepth;
+ // Paper end - Track codec depth
public FriendlyByteBuf(ByteBuf source) {
+ this.adventure$locale = PacketEncoder.ADVENTURE_LOCALE.get(); // Paper - track player's locale for server-side translations
@@ -0,0 +1,51 @@
--- a/net/minecraft/network/codec/ByteBufCodecs.java
+++ b/net/minecraft/network/codec/ByteBufCodecs.java
@@ -378,6 +_,48 @@
};
}
+ // Paper start - Track codec depth
+ static <B extends FriendlyByteBuf, V> StreamCodec<B, V> trackDepth(final StreamCodec<B, V> codec) {
+ return new StreamCodec<>() {
+ @Override
+ public V decode(B buffer) {
+ buffer.trackCodecDepth = true;
+ try {
+ return codec.decode(buffer);
+ } finally {
+ buffer.trackCodecDepth = false;
+ buffer.codecDepth = 0;
+ }
+ }
+
+ @Override
+ public void encode(B buffer, V value) {
+ codec.encode(buffer, value);
+ }
+ };
+ }
+
+ static <B extends FriendlyByteBuf, V> StreamCodec<B, V> increaseDepth(final StreamCodec<B, V> codec) {
+ return new StreamCodec<>() {
+ @Override
+ public V decode(B buffer) {
+ if (!buffer.trackCodecDepth) {
+ return codec.decode(buffer);
+ }
+ if (++buffer.codecDepth > 64) {
+ throw new DecoderException("Too deep");
+ }
+ return codec.decode(buffer);
+ }
+
+ @Override
+ public void encode(B buffer, V value) {
+ codec.encode(buffer, value);
+ }
+ };
+ }
+ // Paper end - Track codec depth
+
static <B extends ByteBuf, V> StreamCodec<B, Optional<V>> optional(final StreamCodec<B, V> codec) {
return new StreamCodec<B, Optional<V>>() {
@Override
@@ -0,0 +1,20 @@
--- a/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java
@@ -17,7 +_,7 @@
);
private static final int MAX_SLOT_COUNT = 128;
private static final StreamCodec<RegistryFriendlyByteBuf, Int2ObjectMap<ItemStack>> SLOTS_STREAM_CODEC = ByteBufCodecs.map(
- Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC, 128
+ Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth), 128 // Paper - Track codec depth
);
private final int containerId;
private final int stateId;
@@ -46,7 +_,7 @@
this.buttonNum = buffer.readByte();
this.clickType = buffer.readEnum(ClickType.class);
this.changedSlots = Int2ObjectMaps.unmodifiable(SLOTS_STREAM_CODEC.decode(buffer));
- this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer);
+ this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth).decode(buffer); // Paper - Track codec depth
}
private void write(RegistryFriendlyByteBuf buffer) {
@@ -0,0 +1,11 @@
--- a/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java
@@ -11,7 +_,7 @@
public static final StreamCodec<RegistryFriendlyByteBuf, ServerboundSetCreativeModeSlotPacket> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.SHORT,
ServerboundSetCreativeModeSlotPacket::slotNum,
- ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC),
+ ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC).apply(ByteBufCodecs::trackDepth), // Paper - Track codec depth
ServerboundSetCreativeModeSlotPacket::itemStack,
ServerboundSetCreativeModeSlotPacket::new
);
@@ -361,7 +361,7 @@
}
@Override
@@ -515,14 +_,52 @@
@@ -515,14 +_,54 @@
@Override
public String getPluginNames() {
@@ -402,6 +402,8 @@
+ }
+
+ public String runCommand(RconConsoleSource rconConsoleSource, String s) {
+ if (s.isBlank()) return ""; // Paper - Do not process empty rcon commands
+
+ rconConsoleSource.prepareForCommand();
+ this.executeBlocking(() -> {
+ CommandSourceStack wrapper = rconConsoleSource.createCommandSourceStack();
@@ -167,7 +167,7 @@
this.player.setLastClientInput(packet.input());
}
@@ -390,17 +_,29 @@
@@ -390,17 +_,22 @@
public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
if (containsInvalidValues(packet.position().x(), packet.position().y(), packet.position().z(), packet.yRot(), packet.xRot())) {
@@ -182,13 +182,6 @@
+ // 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();
+ // CraftBukkit - store current player position
+ double prevX = this.player.getX();
+ double prevY = this.player.getY();
+ double prevZ = this.player.getZ();
+ float prevYaw = this.player.getYRot();
+ float prevPitch = this.player.getXRot();
+ // CraftBukkit end
double x = rootVehicle.getX();
double y = rootVehicle.getY();
double z = rootVehicle.getZ();
@@ -276,7 +269,7 @@
d3 = d - rootVehicle.getX();
d4 = d1 - rootVehicle.getY();
if (d4 > -0.5 || d4 < 0.5) {
@@ -435,18 +_,71 @@
@@ -435,14 +_,44 @@
d5 = d2 - rootVehicle.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false;
@@ -287,68 +280,42 @@
}
rootVehicle.absMoveTo(d, d1, d2, f, f1);
+ this.player.absMoveTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625));
if (flag && (flag2 || !flag3)) {
- if (flag && (flag2 || !flag3)) {
+ // Paper start
+ boolean teleportBack = flag && (flag2 || !flag3);
+ if (!teleportBack) {
+ // Move event - emulating from the vehicle
+ org.bukkit.entity.Entity rootVehicleBukkit = rootVehicle.getBukkitEntity();
+ Location from = new Location(rootVehicleBukkit.getWorld(), x, y, z, f, f1); // Copy from #absMoveTo on teleportBack
+ Location to = rootVehicleBukkit.getLocation();
+
+ // Prevent 40 event-calls for less than a single pixel of movement >.>
+ double delta = Math.pow(from.getX() - to.getX(), 2) + Math.pow(from.getY() - to.getY(), 2) + Math.pow(from.getZ() - to.getZ(), 2);
+ float deltaAngle = Math.abs(from.getYaw() - to.getYaw()) + Math.abs(from.getPitch() - to.getPitch());
+
+ if ((delta > 1f / 256 || deltaAngle > 10f) && !this.player.isImmobile()) {
+ Location oldLoc = to.clone();
+ io.papermc.paper.event.player.PlayerMoveVehicleEvent event = new io.papermc.paper.event.player.PlayerMoveVehicleEvent(this.player.getBukkitEntity(), rootVehicleBukkit, from, to);
+ if (event.callEvent()) {
+ if (event.getTo() != to || !oldLoc.equals(event.getTo())) { // If instance changed or value change, resync
+ Location newTo = event.getTo();
+ rootVehicle.absMoveTo(newTo.x(), newTo.y(), newTo.z(), newTo.getYaw(), newTo.getPitch()); // move the vehicle to the new location
+ this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle)); // resync the vehicle
+ }
+ } else {
+ teleportBack = true;
+ // Reset the above tick -- as ignore checks that they are flying
+ // Most notable if they are in air.
+ this.aboveGroundTickCount = 0;
+ }
+ }
+ }
+ if (teleportBack) {
+ // Paper end
rootVehicle.absMoveTo(x, y, z, f, f1);
+ this.player.absMoveTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle));
return;
}
+
+ // CraftBukkit start - fire PlayerMoveEvent
+ org.bukkit.entity.Player player = this.getCraftPlayer();
+ if (!this.hasMoved) {
+ this.lastPosX = prevX;
+ this.lastPosY = prevY;
+ this.lastPosZ = prevZ;
+ this.lastYaw = prevYaw;
+ 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 = CraftLocation.toBukkit(packet.position(), player.getWorld(), packet.yRot(), packet.xRot());
+
+ // Prevent 40 event-calls for less than a single pixel of movement >.>
+ double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
+ float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
+
+ if ((delta > 1f / 256 || deltaAngle > 10f) && !this.player.isImmobile()) {
+ this.lastPosX = to.getX();
+ this.lastPosY = to.getY();
+ this.lastPosZ = to.getZ();
+ this.lastYaw = to.getYaw();
+ this.lastPitch = to.getPitch();
+
+ Location oldTo = to.clone();
+ PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
+ this.cserver.getPluginManager().callEvent(event);
+
+ // If the event is cancelled we move the player back to their old location.
+ if (event.isCancelled()) {
+ this.teleport(from);
+ return;
+ }
+
+ // If a Plugin has changed the To destination then we teleport the Player
+ // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
+ // We only do this if the Event was not cancelled.
+ if (!oldTo.equals(event.getTo()) && !event.isCancelled()) {
+ this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.PLUGIN);
+ return;
+ }
+
+ // Check to see if the Players Location has some how changed during the call of the event.
+ // This can happen due to a plugin teleporting the player instead of using .setTo()
+ if (!from.equals(this.getCraftPlayer().getLocation()) && this.justTeleported) {
+ this.justTeleported = false;
+ return;
+ }
+ }
+ // CraftBukkit end
this.player.serverLevel().getChunkSource().move(this.player);
rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position());
@@ -455,7 +_,7 @@
rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3);
rootVehicle.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.onGround());
@@ -8,3 +8,21 @@
&& !this.effect.value().applyEffectTick(serverLevel, entity, this.amplifier)) {
entity.removeEffect(this.effect);
}
@@ -408,7 +_,7 @@
.apply(instance, MobEffectInstance.Details::create)
)
);
- public static final StreamCodec<ByteBuf, MobEffectInstance.Details> STREAM_CODEC = StreamCodec.recursive(
+ public static final StreamCodec<net.minecraft.network.FriendlyByteBuf, MobEffectInstance.Details> STREAM_CODEC = StreamCodec.recursive( // Paper - Track codec depth
codec -> StreamCodec.composite(
ByteBufCodecs.VAR_INT,
MobEffectInstance.Details::amplifier,
@@ -420,7 +_,7 @@
MobEffectInstance.Details::showParticles,
ByteBufCodecs.BOOL,
MobEffectInstance.Details::showIcon,
- codec.apply(ByteBufCodecs::optional),
+ codec.apply(ByteBufCodecs::increaseDepth).apply(ByteBufCodecs::optional), // Paper - Track codec depth
MobEffectInstance.Details::hiddenEffect,
MobEffectInstance.Details::new
)
@@ -971,7 +971,7 @@
int i = (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5;
int i1 = 25 - i;
float f = damageAmount * i1;
@@ -1768,24 +_,212 @@
@@ -1768,24 +_,219 @@
}
}
@@ -984,7 +984,11 @@
+ if (invulnerabilityRelatedLastDamage == 0) return 0D; // no last damage, no reduction
+ // last damage existed, this means the reduction *technically* is (new damage - last damage).
+ // If the event damage was changed to something less than invul damage, hard lock it at 0.
+ if (d < invulnerabilityRelatedLastDamage) return 0D;
+ //
+ // Cast the passed in double down to a float as double -> float -> double is lossy.
+ // If last damage is a (float) 3.2D (since the events use doubles), we cannot compare
+ // the new damage value of this damage instance by upcasting it again to a double as 3.2D != (double) (float) 3.2D.
+ if (d.floatValue() < invulnerabilityRelatedLastDamage) return 0D;
+ return (double) -invulnerabilityRelatedLastDamage;
+ };
+ final float originalInvulnerabilityReduction = invulnerabilityReductionEquation.apply((double) amount).floatValue();
@@ -1118,7 +1122,10 @@
+
+ // Apply damage to armor
+ if (!damageSource.is(DamageTypeTags.BYPASSES_ARMOR)) {
+ float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT));
+ float armorDamage = (float) event.getDamage();
+ armorDamage += (float) event.getDamage(DamageModifier.INVULNERABILITY_REDUCTION);
+ armorDamage += (float) event.getDamage(DamageModifier.BLOCKING);
+ armorDamage += (float) event.getDamage(DamageModifier.HARD_HAT);
+ this.hurtArmor(damageSource, armorDamage);
+ }
+
@@ -1,14 +1,6 @@
--- a/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/net/minecraft/world/entity/projectile/ThrownPotion.java
@@ -9,6 +_,7 @@
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponents;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffect;
@@ -82,51 +_,87 @@
@@ -82,51 +_,86 @@
@Override
protected void onHit(HitResult result) {
super.onHit(result);
@@ -28,12 +20,12 @@
+ } else if (true || potionContents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply
if (this.isLingering()) {
- this.makeAreaOfEffectCloud(potionContents);
+ showParticles = this.makeAreaOfEffectCloud(potionContents, result); // CraftBukkit - Pass MovingObjectPosition // Paper
+ showParticles = this.makeAreaOfEffectCloud(potionContents, result); // CraftBukkit - Pass HitResult // Paper
} else {
- this.applySplash(
- serverLevel, potionContents.getAllEffects(), result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null
+ showParticles = this.applySplash(
+ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
+ showParticles = this.applySplash( // Paper - Fix potions splash events
+ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass HitResult // Paper - More projectile API
);
}
}
@@ -48,7 +40,7 @@
}
- private void applyWater(ServerLevel level) {
+ private static final Predicate<net.minecraft.world.entity.LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
+ private static final Predicate<LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
+
+ private boolean applyWater(ServerLevel level, @Nullable HitResult result) { // Paper - Fix potions splash events
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
@@ -67,20 +59,19 @@
if (d < 16.0) {
if (livingEntity.isSensitiveToWater()) {
- livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ affected.put(livingEntity.getBukkitLivingEntity(), 1.0);
+ // livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ affected.put(livingEntity.getBukkitLivingEntity(), 1.0); // Paper - Fix potions splash events
}
if (livingEntity.isOnFire() && livingEntity.isAlive()) {
- livingEntity.extinguishFire();
+ extinguish.add(livingEntity.getBukkitLivingEntity());
+ // livingEntity.extinguishFire();
+ extinguish.add(livingEntity.getBukkitLivingEntity()); // Paper - Fix potions splash events
}
}
}
- for (Axolotl axolotl : this.level().getEntitiesOfClass(Axolotl.class, aabb)) {
- axolotl.rehydrate();
+ // Paper start - Fix potions splash events
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callWaterBottleSplashEvent(
+ this, result, affected, rehydrate, extinguish
+ );
@@ -102,14 +93,14 @@
}
- private void applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity) {
+ private boolean applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity, @Nullable HitResult result) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API
+ private boolean applySplash(ServerLevel level, Iterable<MobEffectInstance> effects, @Nullable Entity entity, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - Fix potions splash events & More projectile API
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(LivingEntity.class, aabb);
+ java.util.Map<org.bukkit.entity.LivingEntity, Double> affected = new java.util.HashMap<>(); // CraftBukkit
if (!entitiesOfClass.isEmpty()) {
Entity effectSource = this.getEffectSource();
@@ -135,33 +_,57 @@
@@ -135,12 +_,31 @@
double d = this.distanceToSqr(livingEntity);
if (d < 16.0) {
double d1;
@@ -120,69 +111,45 @@
d1 = 1.0 - Math.sqrt(d) / 4.0;
}
- for (MobEffectInstance mobEffectInstance : effects) {
- Holder<MobEffect> effect = mobEffectInstance.getEffect();
- if (effect.value().isInstantenous()) {
- effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1);
- } else {
- int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5));
- MobEffectInstance mobEffectInstance1 = new MobEffectInstance(
- effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
- );
- if (!mobEffectInstance1.endsWithin(20)) {
- livingEntity.addEffect(mobEffectInstance1, effectSource);
- }
- }
- }
- }
- }
- }
- }
+ affected.put(livingEntity.getBukkitLivingEntity(), d1);
+ // CraftBukkit start
+ }
+ }
+ }
+ }
+ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, result, affected);
+ if (!event.isCancelled() && entitiesOfClass != null && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process
+ if (!event.isCancelled() && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process
+ Entity effectSource = this.getEffectSource();
+ for (org.bukkit.entity.LivingEntity victim : event.getAffectedEntities()) {
+ if (!(victim instanceof org.bukkit.craftbukkit.entity.CraftLivingEntity craftLivingEntity)) {
+ continue;
+ }
+ net.minecraft.world.entity.LivingEntity livingEntity = craftLivingEntity.getHandle();
+ LivingEntity livingEntity = craftLivingEntity.getHandle();
+ double d1 = event.getIntensity(victim);
+ // CraftBukkit end
+ for (MobEffectInstance mobEffectInstance : effects) {
+ Holder<MobEffect> effect = mobEffectInstance.getEffect();
+ // CraftBukkit start - Abide by PVP settings - for players only!
+ if (!this.level().pvpMode && this.getOwner() instanceof ServerPlayer && livingEntity instanceof ServerPlayer && livingEntity != this.getOwner()) {
+ MobEffect mobEffect = effect.value();
+ if (mobEffect == net.minecraft.world.effect.MobEffects.MOVEMENT_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.DIG_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.HARM || mobEffect == net.minecraft.world.effect.MobEffects.BLINDNESS
+ || mobEffect == net.minecraft.world.effect.MobEffects.HUNGER || mobEffect == net.minecraft.world.effect.MobEffects.WEAKNESS || mobEffect == net.minecraft.world.effect.MobEffects.POISON) {
+ continue;
+ }
+ }
+ {
+ {
+ // CraftBukkit end
+ if (effect.value().isInstantenous()) {
+ effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1);
+ } else {
+ int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5));
+ MobEffectInstance mobEffectInstance1 = new MobEffectInstance(
+ effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
+ );
+ if (!mobEffectInstance1.endsWithin(20)) {
+ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
+ }
+ }
+ }
+ }
+ }
for (MobEffectInstance mobEffectInstance : effects) {
Holder<MobEffect> effect = mobEffectInstance.getEffect();
if (effect.value().isInstantenous()) {
@@ -151,7 +_,7 @@
effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible()
);
if (!mobEffectInstance1.endsWithin(20)) {
- livingEntity.addEffect(mobEffectInstance1, effectSource);
+ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
}
}
}
@@ -159,9 +_,10 @@
}
}
}
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
- private void makeAreaOfEffectCloud(PotionContents potionContents) {
+ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
+ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - More projectile API
AreaEffectCloud areaEffectCloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
if (this.getOwner() instanceof LivingEntity livingEntity) {
areaEffectCloud.setOwner(livingEntity);
@@ -197,41 +164,30 @@
+ if (!(event.isCancelled() || areaEffectCloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && !areaEffectCloud.potionContents.hasEffects())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
+ this.level().addFreshEntity(areaEffectCloud);
+ } else {
+ areaEffectCloud.discard(null); // CraftBukkit - add Bukkit remove cause
+ areaEffectCloud.discard(null); // add Bukkit remove cause
+ }
+ // CraftBukkit end
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
public boolean isLingering() {
@@ -182,13 +_,25 @@
@@ -182,13 +_,19 @@
private void dowseFire(BlockPos pos) {
BlockState blockState = this.level().getBlockState(pos);
if (blockState.is(BlockTags.FIRE)) {
- this.level().destroyBlock(pos, false, this);
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
+ this.level().destroyBlock(pos, false, this);
+ }
+ // CraftBukkit end
this.level().destroyBlock(pos, false, this);
+ } // CraftBukkit
} else if (AbstractCandleBlock.isLit(blockState)) {
- AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, false))) {
+ AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
+ }
+ // CraftBukkit end
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit
AbstractCandleBlock.extinguish(null, blockState, this.level(), pos);
+ } // CraftBukkit
} else if (CampfireBlock.isLitCampfire(blockState)) {
- this.level().levelEvent(null, 1009, pos, 0);
- CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
- this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)));
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, false))) {
+ this.level().levelEvent(null, 1009, pos, 0);
+ CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
+ this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, false));
+ }
+ // CraftBukkit end
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit
this.level().levelEvent(null, 1009, pos, 0);
CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState);
this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)));
+ } // CraftBukkit
}
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/HangingEntityItem.java
+++ b/net/minecraft/world/item/HangingEntityItem.java
@@ -66,6 +_,19 @@
@@ -66,6 +_,20 @@
if (hangingEntity.survives()) {
if (!level.isClientSide) {
@@ -14,6 +14,7 @@
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ if (player != null) player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
+ return InteractionResult.FAIL;
+ }
+ // CraftBukkit end
@@ -1,5 +1,13 @@
--- a/net/minecraft/world/item/component/BundleContents.java
+++ b/net/minecraft/world/item/component/BundleContents.java
@@ -25,6 +_,7 @@
.flatXmap(BundleContents::checkAndCreate, bundleContents -> DataResult.success(bundleContents.items));
public static final StreamCodec<RegistryFriendlyByteBuf, BundleContents> STREAM_CODEC = ItemStack.STREAM_CODEC
.apply(ByteBufCodecs.list())
+ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth
.map(BundleContents::new, contents -> contents.items);
private static final Fraction BUNDLE_IN_BUNDLE_WEIGHT = Fraction.getFraction(1, 16);
private static final int NO_STACK_INDEX = -1;
@@ -76,6 +_,12 @@
return !stack.isEmpty() && stack.getItem().canFitInsideContainerItems();
}
@@ -0,0 +1,10 @@
--- a/net/minecraft/world/item/component/ChargedProjectiles.java
+++ b/net/minecraft/world/item/component/ChargedProjectiles.java
@@ -16,6 +_,7 @@
.xmap(ChargedProjectiles::new, chargedProjectiles -> chargedProjectiles.items);
public static final StreamCodec<RegistryFriendlyByteBuf, ChargedProjectiles> STREAM_CODEC = ItemStack.STREAM_CODEC
.apply(ByteBufCodecs.list())
+ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth
.map(ChargedProjectiles::new, chargedProjectiles -> chargedProjectiles.items);
private final List<ItemStack> items;
@@ -0,0 +1,10 @@
--- a/net/minecraft/world/item/component/ItemContainerContents.java
+++ b/net/minecraft/world/item/component/ItemContainerContents.java
@@ -22,6 +_,7 @@
.xmap(ItemContainerContents::fromSlots, ItemContainerContents::asSlots);
public static final StreamCodec<RegistryFriendlyByteBuf, ItemContainerContents> STREAM_CODEC = ItemStack.OPTIONAL_STREAM_CODEC
.apply(ByteBufCodecs.list(256))
+ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth
.map(ItemContainerContents::new, contents -> contents.items);
public final NonNullList<ItemStack> items;
private final int hashCode;
@@ -0,0 +1,11 @@
--- a/net/minecraft/world/item/component/UseRemainder.java
+++ b/net/minecraft/world/item/component/UseRemainder.java
@@ -8,7 +_,7 @@
public record UseRemainder(ItemStack convertInto) {
public static final Codec<UseRemainder> CODEC = ItemStack.CODEC.xmap(UseRemainder::new, UseRemainder::convertInto);
public static final StreamCodec<RegistryFriendlyByteBuf, UseRemainder> STREAM_CODEC = StreamCodec.composite(
- ItemStack.STREAM_CODEC, UseRemainder::convertInto, UseRemainder::new
+ ItemStack.STREAM_CODEC.apply(net.minecraft.network.codec.ByteBufCodecs::increaseDepth), UseRemainder::convertInto, UseRemainder::new // Paper - Track codec depth
);
public ItemStack convertIntoRemainder(ItemStack stack, int count, boolean hasInfiniteMaterials, UseRemainder.OnExtraCreatedRemainder onExtraCreated) {
@@ -163,7 +163,7 @@
iterator.remove();
}
+ // Paper start - Fix bees aging inside; use exitTickCounter to keep actual bee life
+ else {
+ else if (level.paperConfig().entities.behavior.cooldownFailedBeehiveReleases) {
+ beeData.exitTickCounter = beeData.occupant.minTicksInHive / 2;
+ }
+ // Paper end - Fix bees aging inside; use exitTickCounter to keep actual bee life
@@ -366,6 +366,11 @@ public class VanillaArgumentProviderImpl implements VanillaArgumentProvider {
return this.converter.convert(this.nmsBase.parse(reader));
}
@Override
public <S> P parse(final StringReader reader, final S source) throws CommandSyntaxException {
return this.converter.convert(this.nmsBase.parse(reader, source));
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
return this.nmsBase.listSuggestions(context, builder);
@@ -46,7 +46,7 @@ public class WrappedArgumentCommandNode<NMS, API> extends ArgumentCommandNode<Co
@Override
public void parse(final StringReader reader, final CommandContextBuilder<CommandSourceStack> contextBuilder) throws CommandSyntaxException {
final int start = reader.getCursor();
final API result = this.pureArgumentType.parse(reader); // Use the api argument parser
final API result = this.pureArgumentType.parse(reader, contextBuilder.getSource()); // Use the api argument parser
final ParsedArgument<CommandSourceStack, API> parsed = new ParsedArgument<>(start, reader.getCursor(), result); // Return an API parsed argument instead.
contextBuilder.withArgument(this.getName(), parsed);
@@ -54,7 +54,8 @@ interface RemovedConfigurations {
path("fixes", "fix-curing-zombie-villager-discount-exploit"),
path("entities", "mob-effects", "undead-immune-to-certain-effects"),
path("entities", "entities-target-with-follow-range"),
path("environment", "disable-teleportation-suffocation-check")
path("environment", "disable-teleportation-suffocation-check"),
path("misc", "light-queue-size")
};
// spawn.keep-spawn-loaded and spawn.keep-spawn-loaded-range are no longer used, but kept
// in the world default config for compatibility with old worlds being migrated to use the gamerule
@@ -327,6 +327,9 @@ public class WorldConfiguration extends ConfigurationPart {
public int day = 5;
}
}
@Comment("Adds a cooldown to bees being released after a failed release, which can occur if the hive is blocked or it being night.")
public boolean cooldownFailedBeehiveReleases = true;
}
public TrackingRangeY trackingRangeY;
@@ -555,7 +558,6 @@ public class WorldConfiguration extends ConfigurationPart {
public Misc misc;
public class Misc extends ConfigurationPart {
public int lightQueueSize = 20;
public boolean updatePathfindingOnBlockUpdate = true;
public boolean showSignClickCommandFailureMsgsToPlayer = false;
public RedstoneImplementation redstoneImplementation = RedstoneImplementation.VANILLA;
@@ -49,6 +49,11 @@ public final class DelayedRegistry<T extends Keyed, R extends Registry<T>> imple
return this.delegate().stream();
}
@Override
public int size() {
return this.delegate().size();
}
@Override
public @Nullable NamespacedKey getKey(final T value) {
return this.delegate().getKey(value);
@@ -181,7 +181,7 @@ public final class FoliaAsyncScheduler implements AsyncScheduler {
private void setDelay(final ScheduledFuture<?> delay) {
this.delay = delay;
this.state = STATE_SCHEDULED_EXECUTOR;
this.state = delay == null ? STATE_SCHEDULED_EXECUTOR : STATE_ON_TIMER;
}
@Override
@@ -233,6 +233,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return this.minecraftRegistry.keySet().stream().map(minecraftKey -> this.get(CraftNamespacedKey.fromMinecraft(minecraftKey)));
}
@Override
public int size() {
return this.minecraftRegistry.size();
}
@Override
public Iterator<B> iterator() {
return this.stream().iterator();
@@ -3053,7 +3053,7 @@ public final class CraftServer implements Server {
@Override
public void restart() {
org.spigotmc.RestartCommand.restart();
CraftServer.this.restart();
}
@Override
@@ -3077,6 +3077,11 @@ public final class CraftServer implements Server {
}
// Spigot end
@Override
public void restart() {
org.spigotmc.RestartCommand.restart();
}
@Override
public double[] getTPS() {
return new double[] {
@@ -1,11 +1,19 @@
package org.bukkit.craftbukkit.entity;
import com.google.common.base.Preconditions;
import net.minecraft.Optionull;
import net.minecraft.world.entity.monster.creaking.Creaking;
import org.bukkit.Location;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.util.CraftLocation;
import org.bukkit.entity.Player;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
public class CraftCreaking extends CraftMonster implements org.bukkit.entity.Creaking {
public CraftCreaking(CraftServer server, Creaking entity) {
public CraftCreaking(final CraftServer server, final Creaking entity) {
super(server, entity);
}
@@ -14,6 +22,28 @@ public class CraftCreaking extends CraftMonster implements org.bukkit.entity.Cre
return (Creaking) this.entity;
}
@Nullable
@Override
public Location getHome() {
return Optionull.map(this.getHandle().getHomePos(), pos -> CraftLocation.toBukkit(pos, this.getHandle().level()));
}
@Override
public void activate(final Player player) {
Preconditions.checkArgument(player != null, "player cannot be null");
this.getHandle().activate(((CraftPlayer) player).getHandle());
}
@Override
public void deactivate() {
this.getHandle().deactivate();
}
@Override
public boolean isActive() {
return this.getHandle().isActive();
}
@Override
public String toString() {
return "CraftCreaking";