This resolves some issues which caused entities to not be resent correctly.
Entities that are interacted with need to be resent to the client, so we resend all the entity
data to the player whilst making sure not to clear dirty entries from the tracker. This makes
sure that values will be correctly updated to other players.
This also adds utilities to aid in further preventing entity desyncs.
This also also fixes the bug causing cancelling PlayerInteractEvent to cause items to continue
to be used despite being cancelled on the server.
For example, items being consumed but never finishing, shields being put up, etc.
The underlying issue of this is that the client modifies their synced data values,
and so we have to (forcibly) resend them in order for the client to reset their using item state.
See: https://github.com/PaperMC/Paper/pull/1896
== AT ==
public net.minecraft.server.level.ChunkMap$TrackedEntity serverEntity
Fixes#11649 - As noted in the issue, when CommandNodes are serialized
they are used as the key in a Map. Their equals()/hashcode() should only
match if they are equal nodes (name & command), but due to the erasure of the command field pre-serialization, nodes with different commands can be mapped onto the same value. This causes the client to interpret both nodes as the same, causing suggestions where they should not.
This is fixed by creating a different no-op command for the
erasure, instead of them holding the same lambda.
== AT ==
public net.minecraft.core.MappedRegistry validateWrite(Lnet/minecraft/resources/ResourceKey;)V
public net.minecraft.resources.RegistryOps lookupProvider
public net.minecraft.resources.RegistryOps$HolderLookupAdapter
Fixes incorrect spigot handling of the invulnerability damage
reduction applied when an already invulnerable entity is damaged with a
larger damage amount than the initial damage.
Vanilla still damages entities even if invulnerable if the damage to be
applied is larger than the previous damage taken. In that case, vanilla
applies the difference between the previous damage taken and the
proposed damage.
Spigot's damage modifier API takes over the computation of damage
reducing effects, however spigot invokes this handling with the initial
damage before computing the difference to the previous damage amount.
This leads to the reduction values to generally be larger than expected,
as they are computed on the not-yet-reduced value.
Spigot applies these reductions after calling the EntityDamageEvent and
*then* subtracts the previous damage point, leading to the final damage
amount being smaller than expected.
This patch cannot simply call the EntityDamageEvent with the reduced
damage, as that would lead to EntityDamageEvent#getDamage() returning
the already reduced damage, which breaks its method contract.
Instead, this patch makes use of the DamageModifier API, implementing
the last-damage-reduction as a DamageModifier.
Spigot uses a no longer valid ClientboundContainerSetSlotPacket with the
slot -1, which would update the carried stack in versions <=1.21.1 but
now leads to an IOOB.
1.21.2 instead introduced the ClientboundSetCursorItemPacket, which this
patch uses instead.
The javadocs for BlockDispenseEvent suggest the ItemStack is a single
item which is being dispensed. Before this fix, sometimes it was the whole
stack before a single item had been taken. This fixes that so the stack size
is always 1.
Players are able to use alt accounts and enderpearls to travel
long distances utilizing the pearls in unloaded chunks and loading
the chunk later when convenient.
This disables that by not saving the thrower when the chunk is unloaded.
This is mainly useful for survival servers that do not allow freeform teleporting.
Note: Currently removed as enderpearls are ticked as long as their owner is online in 1.21.2.
Might be worth to re-add once an option to disable the above vanilla mechanic is added, to
fully prevent enderpearl travel exploits.
== AT ==
public net.minecraft.world.entity.projectile.Projectile ownerUUID
When enabled, ender pearls will not load chunks and will save to the world instead of the player.
== AT ==
public net.minecraft.world.entity.projectile.Projectile cachedOwner
Execute processQueue tasks during sleep: needed for console tab completions, pre join event, etc.
Upstream has set precedent that the bukkit scheduler will still tick during sleep, which avoids some problems
with plugins not accounting for the new sleep feature, but can still lead to others. Because of this we have disabled
sleep by default, which avoids the problem and makes it more obvious to check if this is the cause of issues when
enabled. We also unload chunks during sleep to prevent memory leaks caused by plugin chunk loads.
The mojang client will not remove patterns from a Banner when none
are sent inside of an update packet, given that this is not an expected
flow for them, this is not all too surprising. So, we shall resort to always
sending the patterns over the network for update packets.
Anvils, by default, limit applied enchantment levels to their respective
maximum level. The added API enables plugins to disable this behaviour,
allowing enchantments that are overleveled to be applied via the anvil.
Reduces json size by about 25%
Not sure why advancements even had pretty printing enabled.
My best guess was by accident on mojang's part, especially since stats json files don't have pretty printing.
Spigot still maintains some partial implementation of "tick skipping", a
practice in which the MinecraftServer.currentTick field is updated not
by an increment of one per actual tick, but instead set to
System.currentTimeMillis() / 50. This behaviour means that the tracked
tick may "skip" a tick value in case a previous tick took more than the
expected 50ms.
To compensate for this in important paths, spigot/craftbukkit
implements "wall-time". Instead of incrementing/decrementing ticks on
block entities/entities by one for each call to their tick() method,
they instead increment/decrement important values, like
an ItemEntity's age or pickupDelay, by the difference of
`currentTick - lastTick`, where `lastTick` is the value of
`currentTick` during the last tick() call.
These "fixes" however do not play nicely with minecraft's simulation
distance as entities/block entities implementing the above behaviour
would "catch up" their values when moving from a non-ticking chunk to a
ticking one as their `lastTick` value remains stuck on the last tick in
a ticking chunk and hence lead to a large "catch up" once ticked again.
Paper completely removes the "tick skipping" behaviour (See patch
"Further-improve-server-tick-loop"), making the above precautions
completely unnecessary, which also rids paper of the previous described
incompatibility with non-ticking chunks.
If a plugin sets the health of a living entity above 0 after it has already died, the entity will be "revived".
It will behave the exact same as before, except with the internal "dead" flag set, resulting in 2 behavior changes,
A: it's completely invulnerable to all damage
B: it's unable to pickup items
isValid() for these bugged entities will return true, isDead() will return false, despite the dead flag.
This patch checks that the mob isn't dead before saying its alive.
Also, even if the plugin is responsibly checking !isDead() before modifying health, on very rare circumstances
I am currently unable to replicate, these "revived" entities can still appear
In the case where multiple messages from different players are being processed in parallel, there was a potential race condition where the messages would be sent to the client in a different order than the message signature cache was updated. However, the cache relies on the fact that the client and server get the exact same updates in the same order. This race condition would cause the caches to become corrupted, and any future message received by the client would fail to validate.
This also applies to the last seen state of the server, which becomes inconsistent in the same way as the message signature cache and would cause any messages sent to be rejected by the server too.
In VanillaChestLoot, compasses accidentally have a setdamage loot
function on them, but compasses don't take durability, resulting in a warning.
This patch simply removes attempting to add damage to the compass item.
== AT ==
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftSlots
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftStatus
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftType
public net.minecraft.world.inventory.AbstractContainerMenu resetQuickCraft()V
In worlds that are extremely large (greater than 1TB), it can take an insanely long time to walk the entire world for symlinks.
This patch adds a system property to disable the symlink scan, which can be used to speed up world loading.
Most of the visual artifacts that result from having item merge radius above vanilla levels is from items merging vertically,
which realistically, only happens when a player is dropping items, or items are dropping from breaking a block.
Most of the scenarios where item merging makes sense involves the two item entities being on the same Y level. i.e on the ground next to each other.
This is even more apparent since paper fixed items being able to merge through blocks.
This patch allows us to configure items to only merge horizontally, which is what vanilla does.
This allows us to have both the reduced number of item entities a high item-merge radius provides,
without most of the visual artifacts caused by items merging vertically.
The server validates incoming interaction packets by ensuring the player
sending them is inside their interaction range. For this, the server adds
a magic value, by default 1.0, to the original interaction range to
account for latency issues.
This value however may be too low in high latency environments.
The patch exposes a new configuration option to configure said value.
The recent upstream update moved around the event logic for
EntiyDamageEvent and its derivatives.
However, the event was called on every call to #hurt as it was moved out
of actuallyHurt.
This patch moves the invocation directly before the #actuallyHurt calls,
respective invulnerable timings.
== AT ==
public net.minecraft.commands.arguments.blocks.BlockInput tag
public net.minecraft.commands.arguments.DimensionArgument ERROR_INVALID_VALUE
public net.minecraft.server.ReloadableServerResources registryLookup
public net.minecraft.server.ReloadableServerResources
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Marc Baloup <marc.baloup@laposte.net>