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).