Due to 8f12382e8efc8c39a919af9180dd884caf3720ff, CraftBukkit has
now moved the net.minecraft.server package and org.bukkit.craftbukkit
to versioned package names, breaking all plugins that rely on these
directly.
ProtocolLib was never intended to be updated specifcally for new
versions of Minecraft (hence the index-based system of accessing
packets instead of making wrapper classes), so we will use reflection
to "ignore" this hack entirely. Luckily, ProtocolLib was initially
designed for this in mind, so we don't have to refactor it entirely.
Found an error report in the wild suggesting that getCommand() might
occationally fail (if plugin.yml isn't loaded properly, maybe) and
return NULL instead.
Since the commands are only for administrators and plugin authors,
we'll simply ignore it if this occurs.
Discurage plugins of re-sending cancelled packets, as it makes it
impossible for other plugins to take part in the processing.
Assume plugin A delays transmission of packet X by cancelling the event,
and then retransmitting X outside the filters. It is then impossible
for another plugin B to extend the delay without fighting plugin A
for control over the packet, for instance by decreasing the listener
priority and cancelling first.
It is much better for plugin A to call incrementProcessingDelay() in
an asynchronous listener. Then plugin B can do the same, and the
packet will be sent after both plugins has called
signalProcessingDone().
Bukkit complains if we try to send an async packet on the main thread,
so we will have to add a new background thread that can transmit
packets processed by light-weight packet listeners.
In addition, fixed a bug causing the "uncancel" method in
PacketInjector from not working properly. That bug is as persistent
as a zombie.
Client packets are typically processed asynchronously (in a client's
reader thread), and should never access the Bukkit API directly,
with a few exceptions. This is problematic if you need to cancel a
packet as a response to the Bukkit API, such as the permission system.
Currently, you will have to either cancel the packet - which is
discuraged - sync with the main thread and then re-transmit it outside
the filters, or use an asynchronous thread with callSyncMethod and
wait on the returned future. A better method is needed.
Synchronous processing allows you to run light-weight packet listeners
on the main thread without having to deal with synchronization,
concurrency or the overhead of an additional thread. It can also
process multiple packets per tick with a configurable timeout.
This, along with 7b9d971238, makes it
easy to delay light-weight packets to be synchronously processed.