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.
This was caused by a bug in the abstract interval tree class that would
clear the entire tree instead of the subtree whenever a new entry was
added.
Never roll your own custom collection implementation ...