The permission analyzer validates permission declarations in plugin.yml and cross-checks them against permission usage in your code.
What it checks
This analyzer examines permissions and validates:
Permission naming conventions
Default value validity
Child permission references
Permission usage in code vs declarations
Unused permissions
Issues detected
Invalid permission naming
Permission names should follow naming conventions: lowercase letters, numbers, dots, underscores, and hyphens only.
Permission names with uppercase letters or special characters may cause issues with some permission plugins.
Incorrect:
permissions :
MyPlugin.Admin : # Uppercase letters
description : "Admin permission"
my-plugin@special : # Invalid character @
description : "Special permission"
Correct:
permissions :
myplugin.admin :
description : "Admin permission"
my-plugin.special :
description : "Special permission"
Invalid default value
Permission default values must be one of: op, notop, true, or false.
Valid default values:
op - Only server operators have this permission by default
notop - Everyone except operators has this permission
true - Everyone has this permission by default
false - Nobody has this permission by default
Incorrect:
permissions :
myplugin.use :
default : admin # Invalid!
Correct:
permissions :
myplugin.use :
default : op
myplugin.basic :
default : true
myplugin.vip :
default : false
Undefined child permission
If a permission references child permissions, those children must also be declared.
Incorrect:
permissions :
myplugin.admin :
description : "Admin access"
children :
myplugin.command : # This permission doesn't exist!
true
Correct:
permissions :
myplugin.admin :
description : "Admin access"
children :
myplugin.command :
true
myplugin.command :
description : "Use commands"
default : false
Undeclared permission usage
Permissions used in code should be declared in plugin.yml.
Code using undeclared permission:
public function onCommand ( CommandSender $sender , Command $cmd , string $label , array $args ) : bool {
if ( ! $sender -> hasPermission ( "myplugin.admin" )) {
// This permission isn't in plugin.yml!
return false ;
}
return true ;
}
Add to plugin.yml:
permissions :
myplugin.admin :
description : "Admin permission"
default : op
Unused permission
Permissions declared but never used in code might be unnecessary.
This is an informational warning. The permission might be used in ways the analyzer can’t detect, such as by external plugins.
permissions :
myplugin.legacy :
description : "Old permission no longer used"
# Consider removing if truly unused
How permissions are detected in code
The analyzer finds permission usage by scanning for these method calls:
hasPermission("permission.name")
addAttachment("permission.name")
Example code that will be detected:
if ( $player -> hasPermission ( "myplugin.fly" )) {
// Permission usage detected
}
$attachment = $player -> addAttachment ( $this );
$attachment -> setPermission ( "myplugin.temp" , true );
Permission hierarchies
Use child permissions to create permission hierarchies:
permissions :
# Parent permission grants all children
myplugin.admin :
description : "Full admin access"
default : op
children :
myplugin.command.give :
true
myplugin.command.take :
true
myplugin.bypass :
true
# Individual permissions
myplugin.command.give :
description : "Use /give command"
default : false
myplugin.command.take :
description : "Use /take command"
default : false
myplugin.bypass :
description : "Bypass restrictions"
default : false
# Moderator gets some permissions
myplugin.moderator :
description : "Moderator permissions"
default : false
children :
myplugin.command.give :
true
Best practices
Permission best practices
Use lowercase naming: myplugin.feature.action
Be specific: myplugin.command.fly not just fly
Set appropriate defaults
Document each permission clearly
Use hierarchies for grouped permissions
Prefix with your plugin name
Check permissions before sensitive operations
Complete example
plugin.yml:
name : MyPlugin
version : 1.0.0
main : MyPlugin\Main
api : 5.0.0
permissions :
# Admin - full access
myplugin.admin :
description : "Full admin access"
default : op
children :
myplugin.command.teleport :
true
myplugin.command.gamemode :
true
myplugin.bypass.cooldown :
true
# Commands
myplugin.command.teleport :
description : "Use teleport command"
default : false
myplugin.command.gamemode :
description : "Change gamemode"
default : false
# Features
myplugin.bypass.cooldown :
description : "Bypass command cooldowns"
default : false
myplugin.basic :
description : "Basic plugin features"
default : true
Using permissions in code:
use pocketmine\player\ Player ;
class Main extends PluginBase {
public function teleportPlayer ( Player $player , Vector3 $pos ) : bool {
if ( ! $player -> hasPermission ( "myplugin.command.teleport" )) {
$player -> sendMessage ( "You don't have permission" );
return false ;
}
$player -> teleport ( $pos );
return true ;
}
public function changeGamemode ( Player $player , int $mode ) : bool {
if ( ! $player -> hasPermission ( "myplugin.command.gamemode" )) {
$player -> sendMessage ( "No permission" );
return false ;
}
$player -> setGamemode ( $mode );
return true ;
}
}
When to use permission defaults
default: op
Admin commands
Dangerous operations
Server management features
default: true
Basic features everyone should have
Cosmetic features
Read-only commands
default: false
Premium features
Moderator tools
Anything requiring explicit grant
default: notop
Rarely used
For “punishment” permissions
Special restriction scenarios