This happened because "joining" wasn't cleared until the player was ticked. Runnables (presumably) ran _after_ the player list packet was sent, but before the player was ticked; thus, the player list packet was sent, but not cleared. The fix is to replace joining with hasSentListPacket, which is set immediately before sending any player list packets (thus, if hidePlayer is called after, it sees that the list packet has been sent and sends a new one to reset it). With this fix, the player is added to the list and then removed shortly afterwards.
The reason why running /hideall in the example wouldn't fix the invisibility is because the server already thinks the player's been removed from the list (as they're hidden), and thus doesn't want to send another hide packet. This is correct behavior assuming that they get hidden correctly the first time, which they now do.
More APIs to follow pending feedback of whether this is the preferred implementation. Methods marked as deprecated and subject to change, but work as is.
Up until Minecraft version 1.5 it was not possible to teleport entities
within vehicles. With the 1.5 update came the change in the Minecraft
teleportation logic to dismount before teleporting the entity, if
applicable.
This commit ammends the existing CraftBukkit logic for rejecting
teleportation for entities in vehicles to permit the action. Due to this
change, CraftBukkit is now in-line with Minecraft 1.5 teleportation logic.
Currently, plugins can set a player's display name to null, which could
cause issues for other calls to getDisplayName that aren't expecting a null
value. This changes setDisplayName to follow the same logic as
setPlayerListName, which sets the player's name back to their unmodified
"vanilla" name if it receives a null value as a parameter.
Bans require a name and UUID but our API only allows for a single string
identifier for a ban entry. Until this is sorted out go back to the old
name based setup since we can always get a UUID given a name.
The server's check is for whether or not a player can pass the whitelist
not just if the player is on it. That seems like more useful information
but the API has always just checked if they are on it so this commit
restores that.
Previously no implementation existed to access various additional
information fields regarding bans. This implementation expands on the
information outlined in the sister Bukkit commit to provide access to
the Minecraft implementation of the ban system.
This implementation of the banning API contains 2 new classes which
provide access to the internal workings of the built-in banning
system within Minecraft.
The CraftBanEntry class simply supports the representation of an internal
Minecraft BanEntry object. The data that may be modified within this new
object must be manually saved to the list contained within the
CraftBanEntry using it's save() method.
The CraftBanList class supports the representation of an internal
Minecraft BanList object through proxy methods. These methods do
validation on the passed objects where needed to ensure safe input to the
backed Minecraft objects.
These changes additionally re-route the existing banning API to the newer,
more detailed, system. Functionality prior to this change still behaves
as documented by the contract defined by the methods changed.