We cannot filter this packet purely on the netty thread because our filter
depends on the current camera position (if it's too far, we do want to teleport
it closer) and accessing the camera is only safe from the main thread.
Previously the second part had not been considered which could lead to race
conditions where the camera may not yet exist on the netty thread at time of
handling. These appear to have gotten the wholly inappropriate "just put a null
check around it" treatment, but that means that the filter sometimes doesn't
work (hence the bug report).
This commit changes handling such that all access to `allowMovement` is always
done on the main thread and then moves the filtering there as well. And
therefore filtering should now work properly.
No clue why `getResourceLocationForPlayerUUID` was implemented the way it was,
that commit dates back to 2015 (332c36a), but if the skin isn't loaded yet, it
won't load it, so sometimes it just won't show properly in first person and in
the Player Overview.
This commit just calls `AbstractClientPlayer.getSkinTexture` instead.
Unclear which MC versions are affected. At some point before 1.16.4 something
else was introduced which loads the skin for us, hence why modern versions were
not affected.
On my system, a single scroll tick results in 120 calls, which is fine for the
vanilla camera controller because it has a range of 2000, but the classic
controller only has a range of 36, making it impossible to select anything but
the extremes.
This commit changes the size of the range to match that of the vanilla controller.
Fixes an issue where the world border would move at normal speed when speeding up or slowing down the replay, and also at an incorrect speed when rendering the replay, causing it to get out of sync with the rest of the world.
Co-authored-by: Jonas Herzig <me@johni0702.de>
This fixes the rotation of already existing entities that just got sent to the
client. Those get spawned with their rotation, which we didn't capture. This
commit fixes that by initializing our tracked rotation to NaN and returning the
original rotation until the tracked one is initialized (we do it this way rather
than initializing during the spawn packet handling because there are many spawn
packets, especially with modded, and we cannot possibly inject into all of
them).
This does not fix the rotation of newly placed entities (cause they seem to get
spawned with 0/0 and then get teleported to their correct rotation). The
previous commit fixed that case by capturing the rotation from the teleport
packet.
This fixes the rotation of newly placed entities (cause they seem to get spawned
with 0/0 and then get teleported to their correct rotation, which we didn't
capture).
This does not fix the rotation of already existing entities that just got sent
to the client, those already get spawned with their rotation, which we don't yet
capture. The following commit fixes that.
The `yaw` value of non-client-players is constraint to [0; 360), so when that
boundary is crossed, the `renderYaw` starts interpolating to its goal the
incorrect way round (instead of crossing the 360 boundary as well).
To fix that, we now add the difference between the current `renderYaw` and the
desired one, modulo 360 (but with range (-180; 180]), to the current
`renderYaw`. That way we always take the short way round.
Additionally, because for rendering MC looks at the difference without modulo,
afterwards (and when a new `yaw` is set) we wrap the result around such that the
actual difference is always less than 180 and therefore rendered as intended.
This reverts commit 411eaa4ca8.
The given solution does not work in old versions because those did not use
`getYaw` for hand rendering. Even worse, their headYaw does wrap around and it
does it in a different way than their yaw value, giving a worse result than
without this commit.
MC uses the client-side position of an entity to determine whether it is inside
the simulation range and therefore whether it will get ticked. For some (most)
entities it interpolates the client-side position to match the server-side one
inside of the tick method... no prices for guessing where this goes wrong.
Somewhat similar to the issue we have with chunk unloads which we work around in
FullReplaySender but worse cause they'll get stuck if they ever leave the sim
range even for a single tick, rather then just when their chunk is unloaded.
The `yaw` value of non-client-players is constraint to [0; 360), so when that
boundary is crossed, the `renderYaw` starts interpolating to its goal the
incorrect way round (instead of crossing the 360 boundary as well).
Instead we now use the `headYaw` value, which does not wrap around and as such
does not have this issue.