this was requested and PR'd as far back as 2020 (see #3782).
Since no issue was filed about this, it became forgotten until #5946.
However, #5946 overcomplicates the solution to the problem, and breaks BC without an obvious reason.
since BlockTransaction was designed to be World-agnostic, it can't position() any blocks, since Position requires a World.
This workaround is the best we can do for now; however, it would probably be wise to deprecate getTransaction() in favour of a dedicated getBlocks() method which takes care of this, as BlockPlaceEvent is currently quite obnoxious to use.
While event handlers should not throw exceptions, we need to make sure the timings get stopped in the correct order, because the parent Event timer will be stopped due to using a finally block.
If this happens while the handler timing is still running, a second exception will occur, obscuring the real error.
This change significantly reduces the amount of work done by event handlers. Instead of traversing all of the priorities and event parent chain multiple times, we reduce event handlers down to a simple list, which doesn't require any logic to iterate over.
Previously, calling an event with lots of parents costed more than an event which directly descended from Event.
In addition, we had to do a lot of usually useless work to check all priorities, when in practice, only NORMAL will be used in almost all cases.
This change makes it more cost effective to implement the feature suggested by #5678; however, it will still require additional changes.
this gives a somewhat better overview of events, particularly if many plugins are subscribed to the same costly event (e.g. PlayerMoveEvent).
In addition, it allows us to see the frequency that events are occurring.
closes#5554
This is called just before the packet is decoded, allowing the event to be used to drop packets from clients without wasting CPU time decoding them. This can be particularly useful for mitigating denial-of-service attacks.
including support for separated disconnect reasons and disconnect screen messages (closes#4512)
While the refactoring of kick reason -> kick flag wasn't exactly in my agenda, I realized that these changes would become pretty confusing and inconsistent with other events if they weren't refactored.
Hopefully I don't have to break this API again for a while...
please see #5516 for motivation on this, but I don't think anyone will be complaining - this behaviour made no sense and caused a lot of confusion for people who were trying to set custom ban messages.
BlockPlaceEvent no longer extends BlockEvent, since it's now a multi-block event
getBlockReplaced() is removed
getTransaction() is added
to be honest, BlockPlaceEvent should be something like PlayerBlockPlaceEvent...
this API is simultaneously more powerful and cleaner than the previous system.
The previous system relied on undocumented behaviour and was limited to non-localizable strings.
This enables custom servers to implement their own chat formats (e.g. containing localizable tags) which will be displayed in each player's own language (once per-player language has been properly implemented, anyway).
this allows localizing disconnection screens (at least, once #4512 has been addressed) and the disconnect reasons shown on the console.
We already had disconnect messages implicitly localized in a few places, so this is just formalizing it.
This does break BC with any code that previously passed translation keys as the disconnect screen message, because they'll no longer be translated (only Translatables will be translatated now).