Open SOF3 opened 4 years ago
what "alternative methods"? the whole reason I haven't put forth this proposal yet myself is because there isn't any suitable alternative methods for some scenarios.
most changes on Player methods do not consider BC with plugins using PlayerCreationEvent
citation needed; this is actually the exact reason why #3167 has not yet been merged.
Sending PRs is fool's gold, since usually the changes needed are still specialized to one plugin or another anyway (e.g. economy plugins adding getBalance() or similar), and also because of the duration of time it takes for a PR to get from initial creation to release. That said, any application which doesn't require directly modifying Player functionality doesn't belong in a custom Player class anyway.
Some additional things to consider, which aren't mentioned in the main issue:
PlayerCreationEvent
are non-cooperative. Only one plugin using custom player classes can operate at a time. This goes against PM's entire plugin architecture, which is designed from ground-up to be cooperative.
handleDataPacket()
in the old days when packet handling was embedded into Player
. This is no longer the case since many years.Player
classes are to override protected
or public
methods of Player
to alter behaviour that isn't directly exposed, or to intercept stuff that don't currently have events associated with them.
/** @var CustomPlayerClass */
or instanceof CustomPlayerClass
if the code is to be statically analysable. This ties into the above point: using session classes actually produces cleaner code.Player
for future retrieval, so that objects such as sessions are automatically GC'd when the player disconnects without having to handle PlayerQuitEvent
. This ties back into the earlier point about adding new APIs explicitly designed for this kind of use case.The bottom line is that PlayerCreationEvent
is one gigantic hack that's not fit for any purpose other than enabling plugins to do hacks. These hacks are typically only necessary because of:
Player
class) - these should be rectified by internals improvements$this->getSession($player)->doSomething();
vs
if($player instanceof CustomPlayerClass){
$player->doSomething();
}
Relevant: the problem described in the OP is commonly referred to as the Fragile base class problem.
The fact that PlayerCreationEvent is non-cooperative is not exactly critical in the context of private plugins, but the fragility introduced on the Player class is causing much more potential compatibility and maintainability problems.
This is a problem that extends beyond Player classes, which is the reason why I make liberal use of final
and private
in new code
Applications of
PlayerCreationEvent
are basically as unreliable as using reflections. PocketMine is currently not semver-compliant becausePlayer
internal semantics are not polymorphism-friendly enough; most changes onPlayer
methods do not consider BC with plugins usingPlayerCreationEvent
. Hence, supportingPlayerCreeationEvent
is a maintainability burden and should be removed from the API.Plugins currently using
PlayerCreationEvent
should seek alternative methods. In particular, for public plugins, it is always preferrable to send pull requests to extend PocketMine's API, while private developers unwilling to contribute can still patch the source directly (this is unreliable, butPlayerCreationEvent
is unreliable as well).