pmmp / PocketMine-MP

A server software for Minecraft: Bedrock Edition in PHP
https://pmmp.io
GNU Lesser General Public License v3.0
3.28k stars 1.56k forks source link

Remove PlayerCreationEvent #3473

Open SOF3 opened 4 years ago

SOF3 commented 4 years ago

Applications of PlayerCreationEvent are basically as unreliable as using reflections. PocketMine is currently not semver-compliant because Player internal semantics are not polymorphism-friendly enough; most changes on Player methods do not consider BC with plugins using PlayerCreationEvent. Hence, supporting PlayerCreeationEvent 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, but PlayerCreationEvent is unreliable as well).

dktapps commented 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.

dktapps commented 2 years ago

Some additional things to consider, which aren't mentioned in the main issue:

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:

Example code: sessions vs custom Player classes

$this->getSession($player)->doSomething();

vs

if($player instanceof CustomPlayerClass){
    $player->doSomething();
}
SOF3 commented 1 year ago

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.

dktapps commented 1 year ago

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