registerPackets being called within the constructor made it impossible to create instance objects then used in registerPackets (vs. having to then create the objects in registerPackets).
Instead of creating a void type reader for every single PacketHandler registered, this just directly uses the consumer-like PacketHandler.
The distinction between ValueCreator and the normal PacketHandler was unnecessary given you could also just read something in a ValueCreator instance, effectively just being a consumer of a PacketWrapper instance.
Not perfect, but better. This prevents the path checks from exponentially increasing (if it weren't for the maxProtocolPathSize fail safe).
By default, a path will never go to a protocol version that puts it farther from the desired server protocol version, even if a path existed.
Otherwise as well as previously, *all* possible paths will be checked until a fitting one is found.
Negative examples if the new boolean is set to true:
A possible path from 3 to 5 in order of 3->10->5 will be dismissed.
A possible path from 5 to 3 in order of 5->0->3 will be dismissed.
Negative examples if set to false:
While searching for a path from 3 to 5, 3->2->1 could be checked first before 3->4->5 is found.
While searching for a path from 5 to 3, 5->6->7 could be checked first before 5->4->3 is found.
Assuming custom platforms like Bedrock protocol use the normal registering methods, they will have to change the boolean to false to revert to previous behavior (tho still somewhat better optimized).
Defaulting to submitting to the netty event loop caused issues more often than not - this also removes the `currentThread` flag and instead provides new scheduleSend methods so it is always obvious whether the packet is sent immediately.