After witnessing behavior of the regeneration logs, its clear that Vanilla
has had bugs with saving duplicate entities for a while....
Some entities are saved in multiple chunks, and now we are bringing those duplicates
out that use to never surface.
This mode will analyze if the entity appears to be a duplicate (near the other dupe uuid)
and delete the entity instead.
This should reduce regenerations to entities that are nowhere near each other, and
therefore more likely to be subject to real UUID collisions due to our
previous bug, and therefor should survive the chunk load.
Due to the changes in 1.13, clients will send a tab completion request
for all bukkit commands in order to factor in the lack of support for
brigadier and provide backwards support in the API.
Craftbukkit, however; has moved the chat spam limiter to also interact
with the tab completion request, which while good for avoiding abuse,
causes 1.13 clients to easilly be kicked from a server in bukkit due
to this. Removing the spam limit could cause issues for servers, however,
there is no way for servers to manipulate this without blindly cancelling
kick events, which only causes additional complications. This also causes
issues in that the tab spam limit and chat share the same field but different
limits, meaning that a player having typed a long command may be kicked from
the server.
Splitting the field up and making it configurable allows for server owners
to take the burden of this into their own hand without having to rely on
plugins doing unsafe things.
This patch has been applied to 1.12.2 in order to allow people using
plugins which allow clients of newer versions to connect, this is
not a common practice, however is being done as a level of nicety
given the current status of 1.13
We have a result boolean for this already, and this
method was meant to be "Try from cache, if that fails, look it up"
So NPE'ing there just wasn't correct.
ideally this should of never mattered, as it will only
be hit if you teleport out of an unloaded chunk...
But apparently some people are triggering this.
See #1223
This will help guarantee that entities are always in the
chunk that they are currently located at.
Should hopefully also fix Citizens triggering the "Saved to wrong chunk" message
Vanilla logic here would allow us to remvoe an entity from
its current chunk, and if it was going to move into an unloaded
chunk, that entity would not be added to the unloaded chunk.
This is bad because this will result in the entity being lost!
In almost all cases, the chunk will be loaded, but in the event
it wasn't, instead of losing the entity, load the chunk to add
the entity to it.
Hopefully will (f)ix #1280...
I'm suspicious that Citizens isn't calling things in the same order and causes the current
chunk to not be set, which then bugs removals. Though this doesn't make any sense to me,
so this likely won't fix it...
But if the isAddedToChunk is true, we really should be returning a chunk anyways if its loaded.
A spigot change delays removal of entities from the entity list.
This causes a change in behavior from Vanilla where getEntities type
methods will return dead entities that they shouldn't otherwise be doing.
This will ensure that dead entities are skipped from iteration since
they shouldn't of been in the list in the first place.
Spigot might skip chunk registration changes in removeEntity
which can keep them in the chunk when they shouldnt be if done
during entity ticking.
Should fix some cases where "Entity is still in another chunk section"
Related to #1223
Vanilla logic checks unload queue and overwrites if its in it.
we're triggering this if a chunk unloads, and reloads immediately in same tick.
Added check for unload queue to not treat as duplicate
Also fixed the config setting not even loading
Should fix#1280
Citizens hijacks entity map, and im guessing under the right conditions
the result might actually be null during entity creation
Pre the cache patch, the id is looked up on save, so it was fine.
Now, if its null and the save ID is requested, we will try to look
it up again and cache it if found.
See https://github.com/PaperMC/Paper/issues/1223
Should fix Vanilla bugs
Minecraft is saving invalid entities to the chunk files.
Avoid saving bad data, and also make improvements to handle
loading these chunks. Any invalid entity will be instant killed,
so lets avoid adding it to the world...
This lets us be safer about the dupe UUID resolver too, as now
we can ignore instant killed entities and avoid risk of duplicating
an invalid entity.
This should reduce log occurrences of dupe uuid messages.
Also reduce the logging spam overall.
Setting the flag updates the spawner's delay which stops the spawner from trying to find a new spawn position each tick efter the event was cancelled/aborted which makes it usable for mob stackers/mergers and other plugins that don't actually want any mob to spawn in the spawner cycle but keep the overall behaviour close to vanilla.
This might slightly effect existing plugins that use this event but I doubt anyone really relied on this behaviour, the only possible use case that I can think of is cancelling the event until you find a suitable position in your plugin... and this should be handled by the plugin itself by cancelling and spawning at the position manually.
Cleaned up some implementation notes to use existing Vanilla method for some things.
merged into parent patch
7dd5837d Fixed more stuff (NickAcPT)
09f01353 Remove unsed method (NickAcPT)
e5ea4656 Extend player profile API to support skin changes (NickAcPT)
e67d55d0 Extend player profile API to support skin changes (NickAcPT)
* pull/1250/head:
Fixed more stuff
Remove unsed method
Extend player profile API to support skin changes
Extend player profile API to support skin changes
Due to a bug in 2e29af3df0
which was added all the way back in March of 2016, it was unknown (potentially not at the time)
that an entity might actually change the seed of the random object.
At some point, EntitySquid did start setting the seed. Due to this shared random, this caused
every entity to use a Random object with a predictable seed.
This has caused entities to potentially generate with the same UUID....
Over the years, servers have had entities disappear, but no sign of trouble
because CraftBukkit removed the log lines indicating that something was wrong.
We have fixed the root issue causing duplicate UUID's, however we now have chunk
files full of entities that have the same UUID as another entity!
When these chunks load, the 2nd entity will not be added to the world correctly.
If that chunk loads in a different order in the future, then it will reverse and the
missing one is now the one added to the world and not the other. This results in very
inconsistent entity behavior.
This change allows you to recover any duplicate entity by generating a new UUID for it.
This also lets you delete them instead if you don't want to risk having new entities added to
the world that you previously did not see.
But for those who are ok with leaving this inconsistent behavior, you may use WARN or NOTHING options.
It is recommended you regenerate the entities, as these were legit entities, and deserve your love.
Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile
Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile
This won't happen anyways if the user has
"skip ticking for entities in chunks scheduled for unload" turned on,
but if they don't, protect from this instant killing the entity to
keep it vanilla in behavior
a player may teleport away, and trigger instant despawn
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.