Spigot had code that returned early in chunk add/remove methods.
This was causing our code added to set current chunks and counts to
be skipped over if the entity was default not persistent but made persistent.
This was the source of many issues
Fixes#1208
When interacting with entities with an item, the client will assume
the interaction is successful, and update the held item on the
client. However, if the interaction is cancelled on the server side,
the client will still mistakenly remove/replace the item in hand.
Examples for this are milking cows with a bucket or dyeing sheep.
The bucket is replaced with milk and the dye removed from inventory.
Refresh the player inventory when PlayerInteractEntityEvent is
cancelled to avoid this problem.
The adjacent blocks of doors, double plants, pistons and beds need
to be updated manually from the server when cancelling a block break
from a player, as it otherwise causes the other parts to disappear
on the client.
This is already done for doors but only for the BlockBreakEvent,
not for PlayerInteractEvent. Move the code to a common method
and also handle the other blocks in similar ways.
The extra buffer used to decode the strings sent by the client
in the legacy ping protocol was never released. However, creating
an extra copy of the buffer just to decode it to a string isn't
actually necessary: We can just call toString() directly on the
original buffer.
Additionally, free the buffer in handlerRemoved() to handle cases
where the client never sends enough bytes to form a valid legacy
ping request.
Closes#1197
While this really undoes a lot of the desired performance gains avoiding chunk lookups,
we sadly have to accept this because we are seeing lots of bugs with entities.
Allows you to increase how far to check for a safe place to respawn
a player near their bed, allowing a better chance to respawn the
player at their bed should it of became obstructed.
Defaults to vanilla 1.
In many places where we simply want the current chunk the entity
is in, instead of doing a hashmap lookup for it, we now have access
to the object directly on the Entity/TileEntity object we can directly grab.
Use that local value instead to reduce lookups in many hot places.
This enables us a fast reference to the entities current chunk instead
of having to look it up by hashmap lookups.
We also store counts by type to further enable other performance optimizations in later patches.
This is the best way to get an entity when the world and its UUID are known.
It is faster than Server.getEntity(UUID) because it does not have to iterate all worlds
This fixes a CRITICAL missing part of the Bukkit API due to mistakes on upstream
refusing to implement the Sentient NPC baseclass of all NPC's.
Until now, the Bukkit API has not provided a way for accessing and setting
a non creature entities target.
Although Flying, Slime, Ambient, and Water mobs all supported targets internally,
you were unable to get/set it.
Now with the SentientNPC API and these API's moved down, every sentient NPC has
access to target data.
This only impacted people who used our useSnapshots new API in a plugin,
which obviously was no one as the data result was completely broken.
Merged the NPE check patch into mine since it has to handle it too.
This event is called when an entity receives knockback by another entity. The knockback can be modified in the event. If the event is cancelled the entity is not knocked back.
Also renames patch file to better express what it's doing.
It is presumed that those using this config option intend for
suffocation checks to be disabled in all instances. In doing so, they
inherently assume the advantages and issues associated with removing
said safety check.
If the community expresses a desire for more specific options regarding
the handling of this safety feature, we can investigate providing them.
Fixes GH-1149
Called when a player is firing a bow and the server is choosing an arrow to use.
Plugins can skip selection of certain arrows and control which is used.
Rewrites the Vanilla luck application formula so that luck can be
applied to items that do not have any quality defined.
See: https://luckformula.emc.gs for data and details
-----------
The rough summary is:
My goal was that in a pool, when luck was applied, the pool
rebalances so the percentages for bigger items is
lowered and smaller items is boosted.
Do this by boosting and then reducing the weight value,
so that larger numbers are penalized more than smaller numbers.
resulting in a larger reduction of entries for more common
items than the reduction on small weights,
giving smaller weights more of a chance
-----------
This work kind of obsoletes quality, but quality would be useful
for 2 items with same weight that you want luck to impact
in varying directions.
Fishing still falls into that as the weights are closer, so luck
will invalidate junk more.
This change will result in some major changes to fishing formulas.
-----------
I would love to see this change in Vanilla, so Mojang please pull :)
hashCodes are not allowed to change, however bukkit used a value
that does change, the entityId.
When an entity is teleported dimensions, the entity reference is
replaced with a new one with a new entity ID.
For hashCode, we can simply use the UUID's hashCode to keep
the hashCode from changing.
equals() is ok to use getEntityId() because equals() should only
be true if both the left and right are the same reference.
Since entity ids can not duplicate during runtime, this
check is essentially the same as this.getHandle() == other.getHandle()
However, replaced it too to make it clearer of intent.
To teleport an entity between dimensions, the server makes a copy
and puts the copy in the new location, and marks the old one dead.
If this method got called for the same world in the same tick,
the entity would not have been removed from the UUID map, and the
world readd would fail.
This can be triggered even with a plugin if the entity is teleported
twice in the same tick, from world A to B, then back from B to A.
The re-add to A will fail to add the entity to the world. It will
actually be there, but it will not be visible on the client until
the server is restarted to re-try the add to world process again.
This bug was unlikely to be seen by many due to the double teleport
requirement, but plugins (such as my own) use this method to
trigger a "reload" of the entity on the client.
This improves plugins like Citizens that rely on direct instance of Yggdrasil implementations.
Instead of wrapping, directly extend and override the methods.
Went ahead and wrapped all of the services in prep in the base patch, then features modify what they need
Adds ability to control who receives it and who is the source/sender (vanish API)
the standard API is to send the packet to everyone in the world, which is ineffecient.
This adds a new Builder API which is much friendlier to use.
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.
Fires an event anytime an enderman intends to teleport away from the player
You may cancel this, enabling ranged attacks to damage the enderman for example.
Resolves#1101
reporter of this issue was incorrect and did not verify vanilla logic
vanilla logic only skips ticks if the flag is set
spigots change causes bugs as it now skips ticking and processing
chunk teleportation, which was a bug I fixed many many years ago...
Prior to this change the server would crash when attempting to load a
chunk from a region with bad data.
After this change the server will defer back to vanilla behavior. At
this time, that means attempting to generate a chunk in its place
(and occasionally just not generating anything and leaving small
holes in the world).
Should Mojang choose to alter this behavior in the future, this change
will simply defer to whatever that new behavior is.
It is often difficult to diagnose new issues server admins get when
upgrading to a new server version because the only information they are
able to tell us regarding the server version they are running is
"latest". This commit attempts to mitigate this by keeping track of the
previous version of Paper they were running, which is then reported by
the `/version` or `/paper version` command. This gives us a better idea
of the commits included in the upgrade, which may help diagnose new
issues easier.
This change by spigot ensures that many interactins with chunks,
e.g. getting a list of TEs will cause the chunk to be marked for not
unloading and will block their unload. This is especially true for
servers using Timings (it needs to access the TE list of chunks), or
any plugins which need to access entity/TE lists periodically.
At the time this was re-added, there was concern around how the JIT
would handle the system property that enabled it.
This shouldn't be a problem, and as such we no longer need to block
access to it.
The Vanilla Method Profiler will not provide much to most users however
there is no harm in providing it as an option. For most users, the
recommended and supported method for determining performance issues with
Paper will continue to be Timings.
In some enviroments, the channel limit set by spigot can cause issues,
e.g. servers which allow and support the usage of mod packs.
provide an optional flag to disable this check, at your own risk.
* Make the legacy ping handler more reliable
The Minecraft server often fails to respond to old ("legacy") pings
from old Minecraft versions using the protocol used before the switch
to Netty in Minecraft 1.7.
Due to packet fragmentation[1], we might not have all needed bytes
available when the LegacyPingHandler is called. In this case, it will
run into an error, remove the handler and continue using the modern
protocol.
This is unlikely to happen for the first two revisions of the legacy
ping protocol (used in Minecraft 1.5.x and older) since the request
consists of only one or two bytes, but happens frequently for the
last/third revision introduced in Minecraft 1.6.
It has much larger, variable packet sizes due to the inclusion of
the virtual host (the hostname/port used to connect to the server).
The solution[2] is simple: If we find more than two matching bytes,
we buffer the remaining bytes until we have enough to fully read and
respond to the request.
[1]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h3-11
[2]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h4-13
* Add legacy ping support to PaperServerListPingEvent
Add a new method to StatusClient check if the client is a legacy
client that does not support all of the features provided in the
event.
Don't want to risk mutating players properties in server list (unlikely, but lets be proper)
and Skull also has a setter API, so that should be used too.
* Drop original implementation for old player sample API
* Add extended PaperServerListPingEvent
Add a new event that extends the original ServerListPingEvent
and allows full control of the response sent to the client.
* Implement deprecated player sample API
I mistakenly thought .complete() also checked for textures, which was not the case
So the logic was not working as desired.
Also some undesired logic paths lead to textures of the logging in player being dropped, forcing
us to always load the textures immediately again on login, leading to rate limits.
Everythings now good
the .complete() api now will default specify to also complete textures, but you may
pass false to it to skip loading textures.
Gets the unique ID of the player currently known as the specified player name
In Offline Mode, will return an Offline UUID
This is a more performant way to obtain a UUID for a name than loading an OfflinePlayer
This ensures we look up the name for ID only Profiles
If the profile is in the UserCache, we can get those details quickly
This should avoid some unnecessary round trips.
Additionally, handle profiles for offline mode to use offline UUID's
Bukkit restricts command execution of signs to test if the sender
has permission to run the specified command. This breaks vanilla
maps that use signs to intentionally run as elevated permission.
Bukkit provides an unrestricted advancements setting, so this setting
compliments that one and allows for unrestricted signs.
We still filter sign update packets to strip out commands at edit phase,
however there is no sanity in ever expecting creative mode to not be
able to create signs with any command.
Creative servers should absolutely never enable this.
Non creative servers, enable at own risk!!!
The Craft Scheduler still uses the primary thread for task scheduling.
This results in the main thread still having to do work as part of the
dispatching of async tasks.
If plugins make use of lots of async tasks, such as particle emitters
that want to keep the logic off the main thread, the main thread still
receives quite a bit of load from processing all of these queued tasks.
Additionally, resizing and managing the pending entries for all of
these asynchronous tasks takes up time on the main thread too.
This commit replaces the implementation of the scheduler when working
with asynchronous tasks, by forwarding calls to the new scheduler.
The Async Scheduler uses a single thread executor for "management" tasks.
The Management Thread is responsible for all adding and dispatching of
scheduled tasks.
The mainThreadHeartbeat will send a heartbeat task to the management thread
with the currentTick value, so that it can find which tasks to execute.
Scheduling of an async tasks also dispatches a management task, ensuring
that any Queue resizing operation occurs off of the main thread.
The async queue uses a complete separate PriorityQueue, ensuring that resize
operations are decoupled from the sync tasks queue.
Additionally, an optimization was made that if a plugin schedules
a single, non repeating, no delay task, that we immediately dispatch it
to the executor pool instead of scheduling it. This avoids an unnecessary
round trip through the queue, as well as will reduce the size growth of the
queue if a plugin schedules lots of asynchronous tasks.
This seems completely pointless, as packet dispatch uses .writeAndFlush.
Things seem to work fine without implicit flushing, but incase issues arise,
provide a System property to re-enable it using improved logic of doing the
flushing on the netty event loop, so it won't do the flush on the main thread.
Renable flushing by passing -Dpaper.implicit-flush=true
This will force the saves to spread over multiple ticks even when many
players auto save interval is aligned, avoiding spikes on large servers.
Closes#1021
Plugins were abusing this to dispatch commands async anyways.
We will no longer check that flag, and force all commands to be ran sync.
Use a different boolean for allowing things go to through on shutdown/restart instead.
Resolves#1004Resolves#1005
- Lots of itemstack cloning removed. Only clone if the item is actually moved
- Return true when a plugin cancels inventory move item event instead of false, as false causes pulls to cycle through all items.
However, pushes do not exhibit the same behavior, so this is not something plugins could of been relying on.
- Add option (Default on) to cooldown hoppers when they fail to move an item due to full inventory
- Skip subsequent InventoryMoveItemEvents if a plugin does not use the item after first event fire for an iteration
This is adds basic item meta for armor stands. It does not add all
possible metadata however.
There are armor, hand, and equipment types, as well as position data
that can also be added here. This initial implementation should serve as
a starting point for future additions in this area.
Fixes GH-559
This is a source of MAJOR lag for hoppers, as well as a gameplay bug.
This removes the necessity to disable the cat on chest behavior to improve performance.
now performance will be improved even if you have cat chest detection on.
Allows plugins to populate profile properties from local sources to avoid calls out to Mojang API
to fill in textures for example.
If Mojang API does need to be hit, event fire so you can get the results.
This is useful for implementing a ProfileCache for Player Skulls
This simply provides the base API to create the objects. Further commits will come that adds
adds usage of this API to existing GameProfile based API's, as well as new API's.
This event can be used for when you want to exclude a certain player
from triggering monster spawns on a server.
Also a highly more effecient way to blanket block spawns in a world
Adds an event to fire before an Entity is created, so that plugins that need to cancel
CreatureSpawnEvent can do so from this event instead.
Cancelling CreatureSpawnEvent rapidly causes a lot of garbage collection and CPU waste
as it's done after the Entity object has been fully created.
Mob Limiting plugins and blanket "ban this type of monster" plugins should use this event
instead and save a lot of server resources.
See: https://github.com/PaperMC/Paper/issues/917
Limit the number of generations that can occur in a single tick, forcing them
to be spread out more.
Defaulting to 10 as an average generation is going to be 3-6ms, which means 10 will
likely cause the server to lose TPS, but constrain how much.
This should result in no noticeable speed reduction in generation for servers not
lagging, and let larger servers reduce this value according to their own desires.
add a system property to allow people to tweak how long the server
will wait for a reply. There is a compromise here between lower and higher
values, lower values will mean that dead connections can be closed sooner,
whereas higher values will make this less sensitive to issues such as spikes
from networking or during connections flood of chunk packets on slower clients,
at the cost of dead connections being kept open for longer.
Instead of overriding add within the queue, never add runnables to the
queue if the light queue is disabled.
This change is made to make timings reports and stacktraces less
confusing for administrators, who prior to this change, would have seen
the lighting queue referenced in both, regardless of whether or not it
was enabled.
This change should not affect performance, nor is it made with the
intent to.
This allows plugins that give players the ability to apply the experience
points to the Item Mending formula, which will repair an item instead
of giving the player experience points.
Both an API To standalone mend, and apply mending logic to .giveExp has been added.
Fired when the server is about to merge 2 experience orbs
Plugins can cancel this if they want to ensure experience orbs do not lose important
metadata such as spawn reason, or conditionally move data from source to target.
This ensures that enchants are never added in inconsistent order.
The client shows the enchants in a sorted order already
This will auto fix previously created items too on load.
Spigot, by default, disables several mechanisms around how chunks are
lit, if ever, which has forced them to always send chunks before vanilla
would consider them ready to send, causing for lots of issues around
lighting glitches.
Shamefully, the amount of work to relight chunks can be detremental
to some servers, meaning that forcibily disabling light updates can
cause major performance issues.
as such, we make a compromise; if this "feature" is disabled, we will
only send chunks which are actually ready to be sent, otherwise, we
will always send chunks.
Let plugins be able to control tab completion of commands and chat async.
This will be useful for frameworks like ACF so we can define async safe completion handlers,
and avoid going to main for tab completions.
Especially useful if you need to query a database in order to obtain the results for tab
completion, such as offline players.
Also adds isCommand and getLocation to the sync TabCompleteEvent
In 1.12, Spigot improved their blockstate implementation to take a full
copy of the TE, this allows for a much better snapshot in that it will
actually retain all of the TE's state, it is a much more expensive
implementation. This is also implicated with their backwards compat
for inventories meaning that accessing of a snapshots inventory of a
placed block will actually access the inventory of the live TE, making
creation of a snapshot redundant if the only intent is to interact with
the TEs inventory.
Hoppers are a horrible hit, every attempt to transfer an ItemStack will
result in two TileEntity snapshots, with two hoppers and a double chest
ontop, I managed to log 380 cases per second where a snapshot would have been
taken in cases where the snapshot is redundant.