Hi there, i just wrote a pretty huge permission management plugin (including groups, inheritances, rank ladders, user & group prefixes, ...) and i'm wondering about how to handle wildcards (permissions containing *). As far as i know those wildcards were a bukkit feature and part of craftbukkit code (since i didn't develop a permissions plugin in bukkit, i'm not sure)? Does PMMP support a similar permission wildcard feature? If not, might there be an option to implement a wildcard mechanism plugin-side (i don't see any since you need to predict all possible sub-permissions)? Btw. i'm thinking of releasing this plugin to publicity. Is a GitHub account really necessary to release things on poggit? I never used GitHub for prior software development and i don't really want to start with it now only because of poggit. Greetings, Michel5F30
Reinvent the wheel? Just take a look on how PurePerms did it. To be honest, I don't quite get what You're asking for, permissions are handled by PocketMine. You are simply referring to permission that has child nodes (nodes? childs? can't remember), and when you give player that permission, all of it's childrens will be granted aswell. Oh yeah, tip: Read the source of the API you are writing for. No more spoon feeding. I'm sure You'll find your answer there.
theres nothing wrong with reinventing the triangle wheel to make it more rounder tip for OP: pureperm just try to get child permission nodes of say a.b if it's a wildcard it sets all the child note to a positive
Of course they are... but by looking into the sourcecode of "pocketmine\permission\PermissibleBase", it doesn't look like PM is using any of this "pocketmine\permission\Permission" child mechanism. I developed my plugin by this guide, the PM doxygen and looking through the PM sourcecode. I didn't find many things regarding childs. PM only seems to save an array of string (the permission name) and boolean (the permission value TRUE / FALSE). Maybe i miss the obvious... i'll try some things, starting with this: EDIT: "pocketmine\permission\PermissibleBase#recalculatePermissions" does some child stuff, so it might work out. EDIT2: It does not. Final solution see below.
also see https://github.com/PurePlugins/PurePerms/blob/master/src/_64FF00/PurePerms/PurePerms.php#L723
I encountered a problem. By trying to get all registered permissions like using "pocketmine\plugin\PluginManager#getPermissions" or similar, a permission needs to be registered. Most plugins are just using "pocketmine\Player#hasPermission" to check a permission by a string, which doesn't need this permission to be registered, so there is no possible option to find it out? Example code of any plugin (which should be affected by my permission plugin): PHP: public function onChat(PlayerChatEvent $event) { if ($event->getPlayer()->hasPermission("test.a")) $event->getPlayer()->sendMessage("You have got \"test.a\""); else $event->getPlayer()->sendMessage("You haven't got \"test.a\"");} Since the permission "test.a" is only given within the sourcecode of any other plugin, it's not a registered permission, so i can't receive it by "pocketmine\plugin\PluginManager#getPermissions", so i can't set it as TRUE, if the player has "test.*". @Primus do you get my problem now? @Thunder33345 thanks a lot so far. Spoiler: EDIT: For better understanding Part of my permissions plugin: PHP: $this->main->getServer()->getPluginManager()->getPermissions();// does NOT return "test.a", so how may I find out about "test.a" and set it as TRUE, when the player has "test.*"
I have had a look into the sourcecode of Bukkit's PermissionsEx. It seems to use the only possible option, replacing the players PermissibleBase by their own class which extends PermissibleBase. This gives the opportunity to hook into the #hasPermission command and execute a custom permission evaluation. This basically might be possible in pocketmine, too. Creating your own class which extends "pocketmine\permission\PermissibleBase" and make your own permission evaluation, which supports wildcards recognized by strings split by dot. I just have no idea, if there is something like java reflections for PHP. You would need to replace the private class field "\pocketmine\Player#perm" by our own classes instance... Not sure if it is worth the effort. EDIT: PHP reflection is a real thing... http://php.net/manual/de/class.reflection.php EDIT2: Just tested reflections... it really seems to be possible like described above.
I'm pretty sure to get it handled liked described before. For who is interested, this is my approach: PHP: namespace michel5f30\permission;/* * ... some imports ... */class Main extends PluginBase { /* * ... some other variables ... */ private $permProp; public function onLoad() { $this->getLogger()->info("Hooking into pocketmine..."); $playerClass = new \ReflectionClass("\pocketmine\Player"); $this->permProp = $playerClass->getProperty("perm"); $this->permProp->setAccessible(true); } public function invokePerms(Player $player) { $this->permProp->setValue($player, new PermissibleExtension($player)); } /* * ... some other code ... */} PHP: namespace michel5f30\permission;use pocketmine\permission\PermissibleBase;class PermissibleExtension extends PermissibleBase { /* * here Comes my own #hasPermission method * > which needs to do exactly the same than "pocketmine\permission\PermissibleBase#hasPermission" * > plus evaluating wildcards */} PHP: namespace michel5f30\permission;/* * ... some imports ... */class Events implements Listener { public function onPreLogin(PlayerPreLoginEvent $event) { $this->main->invokePerms($event->getPlayer()); // main is my plugin instance passed by constructor } /* * ... some other code ... */} Spoiler: @Primus I actually did not. I found it at https://github.com/PEXPlugins/PermissionsEx. I'll mark the thread as solved until i might encounter new problems. And yes, this will exclude all entities and consolesenders from using wildcards (players only), but i don't care about them (yet).
Thanks for the hint. But i'm pretty sure it will only find registered permissions by the plugin.yml of each plugin? The hard thing is to handle not registered permissions like in the PHP example at #6, just checked by #hasPermission. Most people doesn't register their permissions in the plugin.yml (at least i guess so). And i want unregistered permissions to be handled. Btw. the code above is approved as working: PHP: namespace michel5f30\permission;use pocketmine\permission\PermissibleBase;use pocketmine\permission\Permission;use pocketmine\permission\ServerOperator;class PermissibleExtension extends PermissibleBase { private $main; public function __construct(Main $plugin, ServerOperator $opable) { $this->main = $plugin; parent::__construct($opable); } public function hasPermission($name) : bool { if($name instanceof Permission) $this->main->getLogger()->info("Checking for " . $name->getName()); else $this->main->getLogger()->info("Checking for " . $name); return parent::hasPermission($name); }} Code: [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.a [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.b [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.c [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.d [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.e [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.f [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.g EDIT: I might implement a PlayerPermissionCheckEvent...
Actually plugins should register the permissions in plugin.yml. If they do not, they have a problem. Maybe we should check it in the hasPermission() call...
While my bukkit times i mostly did not register them. And i don't know why i should now... #hasPermission(string) works flawlessly. Ok, maybe registering the permissions you're checking for might be a more safer software structure... but writing this permission YAML really is annoying work. I would recommend to register not registered permissions when they are checked for. This would make permissions inside of the plugin.yml superfluous? EDIT: Of course an administrator using a plugin needs to know all permissions in detail. This is why a proper documentation is necessary at the download page. But i don't know any administrator, who reads the plugin.yml when he/she searches a permission.
The permissions API was developed single-handedly by @shoghicp based on Bukkit's permissions system, and after that, remained the least touched part of the software because of the unclear aims of what we really want. Permissions are supposed to be registered if they are to be listed in a permissions manager. The permissions API is very poorly documented, after all... (Just as everything else @shoghicp developed in the first few months of core-rewrite) I don't think dynamically registering permissions would be helpful. Permission plugins just can't rely on these dynamic values if they scan them at startup.
It has never (maybe not 'never' but in most cases - usually) caused an issue. Can you give any example situation from user perspective?
What exactly has never caused an issue and what situation you want a example for? I pointed out several things in the post you quoted.
If you could document it in the download page, why don't you just document it in the plugin.yml and link users to the plugin.yml in the download page(+_+)
That... would be too simple i guess. I'm quite surprised, that i actually never thought of that... Anyway, there always will be plugins checking for permissions without registring them (except pmmp would check it while #hasPermission is executed and disables the calling plugin or throws an exception, which i wouldn't like i guess). So this is why i want to hook into PermissibleBase to be able to handle wildcards on not registered permissions (btw. i'm still not sure how i will do that since i won't iterate over all permissions due to performance reasons).
I am thinking about rewriting the permissions system. The hasPermission() layer will be backward-compatible, but it will make sure the permission was registered. It is really a mistake that it wasn't.