Commit Graph

203 Commits

Author SHA1 Message Date
799183e13e make use of phpstan class-string in some areas 2020-01-30 22:23:11 +00:00
260ac47588 add some phpstan array types 2020-01-30 22:23:11 +00:00
d94995e161 populate missing array value types in plugin namespace 2020-01-30 21:17:13 +00:00
f624871b3f strip extra blank lines (php-cs-fixer) 2020-01-22 14:50:29 +00:00
9cd6b3e1c7 fix remaining multiline @var annotations 2020-01-22 14:44:36 +00:00
9f44adf04a pass 2, manual removal of incorrect non-nullable @param for nullable native types 2020-01-21 15:44:34 +00:00
c4793241f5 Mass removal of useless @param/@return PHPDoc annotations, pass 1 2020-01-21 15:10:18 +00:00
1cc7027f92 plugin: populate missing return type information 2020-01-19 17:09:33 +00:00
0587d03c03 PluginDescription: add native return types to private functions 2020-01-18 17:57:24 +00:00
c7f1b605f2 PluginBase: remove useless duplicate doc comment from onLoad() stub 2020-01-18 17:56:44 +00:00
17720041a3 phpdoc: populate missing parameter typeinfo 2020-01-11 21:53:24 +00:00
1eedac87b2 added missing @var property types (reported by phpstan) 2020-01-09 14:13:54 +00:00
cda3e6f4dc PluginDescription: clean up type information for extensions field 2020-01-09 11:20:01 +00:00
73d4ff6b52 more missed function imports 2019-12-09 21:16:35 +00:00
ecb2e6e3af PluginManager: remove useless information from softDepend debug
we don't report the parameter type anywhere else, and since PHP doesn't support overloading, we don't need to.
This fixes PHPStan 0.12 complaints about ReflectionNamedType. I figured this was the best solution instead of adding an extra few lines of code.
2019-12-04 10:17:25 +00:00
25ff90b2c6 PluginManager: fix chained softdepend plugins load order
Test case:
- plugin2 depends on nonexistent plugin1
- plugin3 depends on plugin2

At random occasions, plugin3 would be loaded before plugin2, because plugin2 load would be deferred in the expectation of plugin1 being loaded. This would result in the assumption that plugin3's softdepend plugins would not be loaded, so they were ignored.
We fix this problem by removing missing plugins from softdepend if they were not present on a scan of the directory. This way, we don't ignore any unresolved deferred dependency resolutions.
2019-08-16 16:46:59 +01:00
73d3f9f7f7 Fix loadbefore sometimes not working (#3040)
loadbefore operates by injecting self into the target plugin's soft-dependencies. The problem is that these soft-dependency lists are overwritten if the target plugin's soft-dependencies are resolved after the loadbefore of the origin plugin.
2019-07-17 16:52:29 +01:00
025b72e2f2 Randomize the order of plugins retrieved from disk, fixes #2945 (#2948)
On most filesystems, plugins are loaded in lexical order because that's how the filesystem gives the files to us. This is a problem because it can hide bugs with dependency resolution on specific platforms with this behaviour, while inexplicably breaking on other platforms where the load order is different or undefined.

This change prevents plugins depending on any file yield order by randomizing the order in which plugin files are checked for loadability.
2019-05-31 17:11:20 +01:00
2540dacdd7 PluginManager: fixed suffix split handling 2019-02-23 10:51:06 +00:00
4b9a142a5d Import global functions and constants for enhanced performance
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.
2019-01-04 20:43:15 +00:00
46d9475568 Use Utils::getNiceClosureName() in PluginManager 2018-11-11 19:50:07 +00:00
5284ad0346 Merge branch 'release/3.3' into release/3.4 2018-11-11 11:15:46 +00:00
b19b3134ad PluginManager: reduce unnecessary indentation 2018-11-11 11:15:27 +00:00
7cf36f460b Merge branch 'release/3.3' into release/3.4 2018-11-10 22:37:08 +00:00
9156cbc269 PluginManager: Make registerEvents() check order more logical
Prioritize validating that the function is actually a handler, before trying to parse its doc comment.
2018-11-10 22:36:46 +00:00
6dd2597934 Merge branch 'release/3.3' into release/3.4 2018-10-21 18:17:07 +01:00
45c9caa38c Fixup some formatting issues 2018-10-21 18:15:25 +01:00
a3552875cb Merge branch 'release/3.2' into release/3.3 2018-10-07 17:48:26 +01:00
d259b2c9ee Merge branch 'release/3.1' into release/3.2 2018-10-07 17:48:19 +01:00
10fa74b417 Make clear that Plugin->setEnabled() is @internal
Use of this by plugins will produce a lot of undefined behaviour, such as event handlers not being unregistered, scheduled tasks not being removed, and registered permissions causing memory leaks.
2018-10-07 17:48:11 +01:00
1dd6591ac1 Migrate a bunch of PluginManager->callEvent() usages to Event->call
This has the triple bonus effect of a) making a lot of code easier to read, b) reducing Server::getInstance() usages, and c) removing a whole bunch of Server dependencies.

The network and block namespaces are untouched by this commit due to potential for merge conflicts. These should be dealt with separately on master.
2018-10-05 17:30:06 +01:00
6efef3bbc7 Move event calling functionality to Event->call() method
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.
2018-10-05 16:55:37 +01:00
b1e0f82cbf PluginManager: Stop catching exceptions thrown by event handlers (#2472)
The basic principle here is "if you're not expecting it, don't catch it".

Event handlers are **never** supposed to throw exceptions. If they do throw exceptions, it's usually going to one of two things;
1. Broken code producing an error
2. Code triggering (and not catching) a runtime error

Both 1) and 2) boil down to defective code on the part of the event handler, and thus should not be caught by the caller, but instead allowed to crash the server and produce a crashdump.

It's also undesirable to catch unexpected errors here for a few other reasons
- It leaves the owner of the event handler in an unknown, potentially unstable state
- It allows broken code to cause event handlers to spam the logger in events that happen frequently (for example movement handlers)
- It allows the process to continue down a train of further undefined behaviour, which may lead to more errors or ultimately a crash, so it makes no sense to hold off the inevitable.

This has a few advantages that are not merely inverted disadvantages:
- Crash dumps will now be created and automatically submitted for defective event handlers, allowing quicker issue location, debugging and fixing in plugins without manual user interaction
- Event calling now isn't dependent on Server to work.
2018-10-05 16:46:10 +01:00
c83d12790e Merge branch 'release/3.1' into release/3.2 2018-09-14 17:09:41 +01:00
5863d4c066 Fixed PermissibleBase->clearPermissions() not unsubscribing from permissions that aren't explicitly assigned
This came to light after observing cfb6856634 in a fresh light. I noticed that this fix should not have been necessary because clearPermissions() should have dealt with it. Unfortunately, permissions can be set without being set in PermissibleBase->permissions, so this misses things.
2018-09-14 17:06:32 +01:00
7f0fa2ac3d PluginBase: Do not fill defaults from resources/config.yml (#2316)
This fixes #2219.
2018-08-07 12:33:24 +01:00
bda271ca63 Merge branch 'release/3.1' into release/3.2 2018-07-27 11:47:36 +01:00
4a1ed21e52 PluginManager: Fix patch level check to allow loading the plugin when the server's minor level is higher than the plugins declared minor level. 2018-07-27 11:46:24 +01:00
94352782d5 https://media.giphy.com/media/UAUtB4Oi9U4EM/giphy.gif 2018-07-26 10:31:57 +01:00
8fae79f85b Merge branch 'release/3.1' into release/3.2 2018-07-26 10:25:19 +01:00
695793795e PluginManager: Remove dead $pluginParentTimer left over from 9e4d88a852 2018-07-26 10:25:01 +01:00
9a2845640b Permissions management cleanup (#2332)
* Added a new PermissionManager, remove ridiculous cyclic dependencies of Permissions on Server

Aside from all the other ridiculous design problems with the permission system, the biggest problems are its API. This is, once again, a result of poor API design copied from Bukkit.

This pull request removes all permission-related functionality from `PluginManager` and moves it to the `pocketmine\permission\PermissionManager` class.

As can be observed from the removed code in the diff, the permissions system was previously entirely dependent on the Server, because it needed to get the PluginManager for registering permissions. This is utterly ridiculous. This refactor isolates _most_ permission-related functionality within the `permission` namespace.

As mentioned above, this stupid API is a direct result of copying from Bukkit. If you look at the API documentation for Bukkit for `PluginManager` you will see that the methods I'm deprecating here are also in there.

## Changes
- Added a new `PermissionManager` class. This can be accessed via its singleton `getInstance()` static method.
- Deprecated the following `PluginManager` methods - these will be removed no later than 4.0.0:
  - `getPermission()`
  - `addPermission()`
  - `removePermission()`
  - `getDefaultPermissions()`
  - `recalculatePermissionDefaults()`
  - `subscribeToPermission()`
  - `unsubscribeFromPermission()`
  - `getPermissionSubscriptions()`
  - `subscribeToDefaultPerms()`
  - `unsubscribeFromDefaultPerms()`
  - `getDefaultPermSubscriptions()`
  - `getPermissions()`
2018-07-26 10:21:41 +01:00
40c28f4d26 PluginManager: Automatically create data directories for plugins (#2284) 2018-07-21 15:57:37 +01:00
1d5c741f28 PluginBase: Automatically save default config if it doesn't exist (#2285)
I wasn't sure whether this would be considered a bug fix or a feature. Nonetheless, it's a behavioural change, so it belongs in 3.1 if anywhere.

Prior to this, plugins would be required to call saveDefaultConfig() before calling getConfig() or anything else. Calling getConfig() without saveDefaultConfig() first would generate an empty configuration file. Instead, it now saves the default config before loading it.
2018-07-12 19:25:48 +01:00
7a164a8254 PluginManager: Allow @ignoreCancelled annotation on event handlers to not have parameters (#2294) 2018-07-12 17:12:14 +01:00
9610c55b19 PluginManager: Skip methods not declared by instanceof Listener when registering handlers (#2293)
This is quite an interesting bug. If you have
```php
class A{
    public function onMove(PlayerMoveEvent $event){} //shouldn't be a handler because this class isn't a Listener
}

class B extends A implements Listener{}
```
then
```php
registerEvents(new B, $plugin);
```

then `A::onMove()` will be registered as an event handler even though `A` is not an instanceof `Listener`.

This was observed by noting that plugins which do something like `extends PluginBase implements Listener` causes `registerEvents()` to try and register `PluginBase` methods as event handlers, which could lead to astonishing behaviour.


then A::onMove() will be registered as an event handler even though A is not an instanceof Listener.

This was observed by noting that plugins which do something like "extends PluginBase implements Listener" causes registerEvents() to try and register PluginBase methods as event handlers, which could lead to astonishing behaviour.
2018-07-10 16:59:33 +01:00
2d454ae56f PluginManager: fixed bug in YML commands permission type checking 2018-07-08 16:19:46 +01:00
066c9d4fd4 PluginManager: simplify isPluginEnabled() 2018-07-08 16:16:39 +01:00
34e9e93210 PluginBase: fixed crashing on getConfig() when data dir doesn't exist
I considered making this instead save the default config instead of creating an empty config file, but that would be (albeit minor) a behavioural change which therefore belongs in 3.1.
2018-07-05 19:59:08 +01:00
7b7be9618c PluginBase: fixed plugin task timings showing "Unknown" for plugin name 2018-06-21 12:05:30 +01:00