-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Description
New versions of MC do not include available chunk section mask and for chunk sections decoding a current world height is used.
Due to async packet proccesing there is possible that server changed world for player(RESPAWN packet) while there is some chunks in orebfuscation process what will cause orebfucator to send chunks belong to other world.
This cause some issues:
-
If world height is different then client will fail to decode packet, due to not reading all sections or overeading sections, what should cause disconnect from server. ViaVersion also will fail to transform chunk packets, and will disconnect player (https://pastebin.com/NBqj7jB3).
-
May cause some client chunks artefacts due to some chunks are leaked from old world to new world.
-
New versions introduce some nice packets like Chunk Batch Start/End, Bundle Delimiter, putting some packets to be out of order breaks usage for these packets.
-
Its possible that server may send chunks belong to one world, then player got instanly switched to another world and then when ProtocolLib scheduled packets to be executed in
Orebfuscator async pooltheplayer.getWorld()may return a new world instead of actual world where chunks came from. I think this what happened here: https://pastebin.com/JYdvK9UB
My idea how to resolve this issue:
I think we need an custom packet queue implementation, what will not cause any packet order issues, but will allow parralel chunk obfuscation.
What i mean: When we get chunk packet we start obfuscating process for that chunk (getting neighbours and then actual obfuscation), all next other packets we put into queue. When obfuscation is ready we drain queue until next chunk packet. So we pause all packet sending until chunk obfuscation is done.
I am not sure if this is doable with ProtocolLib. But should not be very hard to implement this queue with some handler in netty pipeline sitting before minecraft encoder. So you can simply put minecraft packet objects into some queue if there is chunk in obfuscation progress, or passthrough it to the next handler. You can still use ProtocolLib for easely reading values from minecraft packet objects.
This approach still requires manual world tracking to know exact chunk section count to read and what world instance to use for getting neighbours. Should not be very hard to map RESPAWN packet dimension field to Bukkit world across multiple server versions.
Reproduction Steps
Currently i just analyzed code and logs, so i didnt tried to replicate it, but i belive it should be easy to replicate with plugin that will constantly teleport player between worlds with different world heights.
Expected Behaviour
No issues with async processing
Orebfuscator Dump
Extra Details
I am using a custom fork with some additions, but i am 100% sure they do not cause this issue.