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.
Certain types, such as ItemStack[], would cause the StructureCompiler
to generate classes with the name CompiledStructure@ParentItemStack[],
which are not legal names.
Instead, we'll replace the brackets with the word Array.
In addition, to accomodate classes with identical names, we'll use
the following naming convention instead:
CompiledStructure$[Canonical name of target]$Canonical name of type],
where the canonical name (net.minecraft.server.ItemStack[]) is
transformed to a legal name by replacing "." to "_" and "[]" to array.
In our example, that would result in the following class name:
net_minecraft_server_ItemStackArray
The problem is that ProtocolLib is using a different naming convention
where each release has a version suffix. So, while we can't use the
update folder to replace the JAR file, it's also not needed since
we can simply add it to the plugins directory directly and remove
the old version on shutdown.