This prevents plugins sending wrong packets at the compiler level (or would, if we had a compiler). It's more robust than a getter for client/server and throwing an exception since a static analysis tool can detect faults created by sending wrong packets from the server. This is also used to deny service to dodgy clients which send wrong packets to the server to attack it.
this is in preparation for clientbound/serverbound packet separation. I did this already on another branch, but the changeset was dependent on a massive refactor to split apart packets and binarystream which i'm still not fully happy with.
This is better for performance because these then don't need to be reevaluated every time they are called.
When encountering an unqualified function or constant reference, PHP will first try to locate a symbol in the current namespace by that name, and then fall back to the global namespace.
This short-circuits the check, which has substantial performance effects in some cases - in particular, ord(), chr() and strlen() show ~1500x faster calls when they are fully qualified.
However, this doesn't mean that PM is getting a massive amount faster. In real world terms, this translates to about 10-15% performance improvement.
But before anyone gets excited, you should know that the CodeOptimizer in the PreProcessor repo has been applying fully-qualified symbol optimizations to Jenkins builds for years, which is one of the reasons why Jenkins builds have better performance than home-built or source installations.
We're choosing to do this for the sake of future SafePHP integration and also to be able to get rid of the buggy CodeOptimizer, so that phar and source are more consistent.
This allows plugins to more easily control the behaviour of server-full, whitelisting and banning. A message can be assigned for each, with a plugin custom reason taking the final priority if set.
This system solves several edge case problems in the Bukkit version by allowing kick reasons to be combined, so that removing one kick reason will roll back the final reason to the next highest, instead of just allowing the player through completely.
Only one message will be shown at point of disconnection, for consistency with the old behaviour.
The message priority is as follows (for all cases, only if set):
- Plugin reason
- Server full
- Whitelist enabled
- Player is banned
This also brings us one step closer to separating Player and NetworkSession.
Previously the only way to deal with this was to cancel the PlayerKickEvent generated by lack of authentication. Now, plugins can decide whether auth should be required for a specific player. The default is whatever xbox-auth is set to in server.properties.
cc @Johnmacrocraft
This cleans up some cargo-cult code poorly copied from Bukkit, which has negative performance effects and also makes internal event handling more complex than necessary.
## API changes
- Removed `EventExecutor` and `MethodEventExecutor`.
- A listener is no longer required for an event handler to be registered. Closure objects can now be used directly provided that they meet the conditions for registration.
- `PluginManager->registerEvent()` signature has changed: the `Listener` and `EventExecutor` parameters have been removed and a `\Closure $handler` has been added in its place.
- `RegisteredListener` now requires a `Closure` parameter instead of `Listener, EventExecutor`.
## Behavioural changes
These changes reduce the execution complexity involved with calling an event handler. Since event calls can happen in hot paths, this may have visible positive effects on performance.
Initial testing reveals a performance improvement of ~15% per event handler call compared to the old method.
This was observed in a recent crashdump where a plugin triggered a recursion error, but the stack trace did not contain any sign of a recursive event call. I conclude that this must have been caused by previous event handlers triggering errors 50 times in order to make the recursion detection break, because the recursion detection did not decrement the counter in cases where an exception was thrown.
These methods:
a) add concrete dependencies
b) are pointless (event->getEntity() instanceof Creature, anyone? an IDE can better understand this as well...)
c) encourage bad code (they don't enforce type contracts the same way an instanceof check does - oh, and why not let's add an is*() for every new mob that gets added ever?
This check is completely unnecessary since handlers get unregistered when a plugin is disabled. Additionally, this is an extremely hot path and this change produces a modest 5% performance improvement to event calls.
This is dependent on the changes made in b1e0f82cbf. This now makes it possible to call events without fetching a Server reference, allowing to eliminate a vast array of Server dependencies.
This solves the age-old issue of PlayerInteractEvent firing twice when a player clicks a block with an item in the hand.
API changes:
- Removed PlayerInteractEvent constants LEFT_CLICK_AIR, RIGHT_CLICK_AIR and PHYSICAL.
- PlayerInteractEvent no longer fires when the player right-clicks the air.
- Added new event PlayerItemUseEvent.
the same behaviour can be achieved by cancelling the event and setting the held item manually. Allowing this to be changed increases the complexity of dealing with survival block picking.