Yes, still an issue in 1.9.2
I believe I know the cause of this bug. FallingSand entities have a special behavior where they delete the block they are inside if it has the same ID and their Time = 0. You can see the 1.7 implementation of this behavior here:
https://github.com/Bukkit/mc-dev/blob/master/net/minecraft/server/EntityFallingBlock.java#L76
The isStatic check above makes this code only run on the server. In the 1.8 code (which is not online for me to link to) this was moved outside the isStatic check and so the client is running it too. Because the Time property is not sent to the client, FallingSand entities always spawn with Time 0 and thus always delete the block.
This bug may work similarly to MC-52881. If incoming packets are processed between when the velocity from the explosion is applied and when it is sent to the client, then friction may be incorrectly applied. I will investigate this when I get a chance.
Hello, I can explain exactly what causes this and provide a patch to fix it.
First of all, the description has it backwards. The player who connected first receives the correct knockback. The later connected player receives less knockback when hit by the earlier connected player.
This happens because the server applies friction to the player's velocity every time it receives a movement packet from the player. The later connected player's serverbound packets are processed in between the hit from the earlier player and the velocity update packet being sent to the client, which is deferred to the end of the tick. So, each of the later player's movement packets in the queue will reduce the knockback velocity, before it is sent to the client. If those movement packets say that the player is on the ground, then ground friction will be applied, which cuts velocity roughly in half every tick, so it only takes a few packets in the queue to reduce knockback to nearly zero.
For players A and B, who connected in that order, the sequence of events looks something like this (this all happens in a single tick):
server processes inbound packets from all players, in the order they connected
server processes an inbound packet from A saying to attack B, which changes B's server velocity (but does not yet update the client)
server processes any number of inbound movement packets from B saying that B is standing on the ground, and applies a tick of ground friction to B's velocity for each one
server ticks all players
server sees that B's velocity changed and sends a velocity update packet to the client
Packets from B attacking A are processed after A's movement packets, so the velocity is NOT reduced before it is sent to the client at the end of the tick, and A receives the full knockback.
The simplest fix for this is probably the one implemented in this Bukkit patch:
https://github.com/OvercastNetwork/SportBukkit/commit/0a6819e11487d6fef0b5bdc4fbd635ef8a512101
That patch simply sends the velocity update to the client immediately after the hit, rather than waiting for the end of the tick. It also does not update the server velocity from the knockback, it just sends it to the client and then forgets about it. This effectively disables server-side velocity tracking entirely.
We have playtested this patch and it works great. It makes melee combat very noticeably less erratic.
An even better fix for this would be to get rid of server velocity entirely, as it does not seem to serve any useful purpose. It is essentially meaningless because it is not affected by player movement at all, only by knockback and gravity. So, the player's server velocity is generally zero, unless they are falling or getting knocked back. And when it is not zero, the friction applied from incoming packets still makes it extremely inaccurate. Also, knockback is the only the only thing that actually causes the server velocity to be sent to the client. At all other times, server velocity is entirely passive.
It would be simpler and more accurate to just give the client exclusive control over velocity (since it already has exclusive control over movement) and for things like knockback to be implemented by sending relative velocity changes (impulses) to the client.
Feel free to contact me for details or clarification of anything.
Fantastic, superbo! I would include dead players in @r as well though. Then it's very consistent and intuitive: anything that selects for location excludes dead players, anything that ignores location includes them.
I'm not sure what bug this change was supposed to fix, but as a mapmaker, I can confirm that this new behavior will be an enormous problem, and I would strongly urge Mojang to come up with a better solution. Note that it is already trivially easy to make a selector that excludes dead players, so I don't understand what benefit would come from forcing them to always be excluded.
My own map, Hoodoo, will be very broken by this, and fixing it may be impractical. I need to detect and run commands on dead players for various reasons and this seems to make that impossible. I would expect many other maps to break as well. Even those that don't do anything particular with dead players are still likely to rely on certain commands always working, e.g. scoreboard changes, setting spawnpoint, and various other things that are perfectly applicable to both living and dead players. If players are effectively appearing and disappearing all the time, things are surely going to break.
Yep, this seems to affect the setblock command in 1.7.2 in the same way. Dispensers always face south, regardless of the data value. But you can change the direction by having a block next to it, so there's that workaround at least.
There is an off-by-one bug that causes you to dismount -1 from the location that is checked when the coordinate is negative. This explains why it will sometimes place you on air or a non-solid block. Again, this only happens when the respective world coordinate is negative.
I tested with 1.4.7 and I'm still getting the same freeze. I would have thought "Fixed long timeout when checking SRV records" was the fix for this, but I guess not. To be sure, I used Wireshark to look at the the network trace and it's definitely the SRV requests that are timing out.
I looked at MC-60 but those symptoms seem different than mine. I'm not experiencing crashes and there's no difference after joining and leaving a server.
I'm still experiencing this in unmodified 1.4.5 client+server. Not sure why the bug was closed.
This has been happening consistently since 1.3, regardless of lag. In SMP, it will kick you for flying if you walk on the fake blocks. It's a big problem for PvP maps where TNT gets used a lot.
I have definitely noticed a new and distinctive freeze lasting about a second and happening every few minutes. I just noticed it in 1.4.3 but it may have also been in 1.4.2. It's not much older than that though. It happens in both the Overworld and the Nether, and I can't correlate it with any particular activity or game event. I'll let you know if I figure anything else out.
It can be fixed with one line of code