Events
HyperPerms fires events when permissions are checked or modified. Listen to these events to integrate with other plugins or implement custom behavior.
Available Events
| Event | Fired When | Cancellable |
|---|---|---|
| PermissionCheckEvent | A permission is checked | No (result modifiable) |
| GroupCreateEvent | A group is created | Yes |
| GroupDeleteEvent | A group is deleted | Yes |
| GroupModifyEvent | A group is modified | Yes |
| UserModifyEvent | User data is modified | Yes |
| UserPromoteEvent | User is promoted on a track | Yes |
| UserDemoteEvent | User is demoted on a track | Yes |
PermissionCheckEvent
Fired every time a permission is checked for a player. Use this to modify permission results or log access.
java
import dev.hyperperms.api.event.PermissionCheckEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class PermissionListener implements Listener {
@EventHandler
public void onPermissionCheck(PermissionCheckEvent event) {
UUID player = event.getUser().getUuid();
String permission = event.getPermission();
boolean result = event.getResult();
// Log the check
System.out.println(player + " checked " + permission + " = " + result);
// Modify the result (use carefully!)
if (permission.equals("special.override")) {
event.setResult(true);
}
}
}Event Properties
getUser()- The user being checkedgetPermission()- The permission node being checkedgetContexts()- The contexts for this checkgetResult()- The calculated resultsetResult(boolean)- Override the result
PermissionCheckEvent fires very frequently. Keep your handler fast to avoid performance issues. Avoid heavy operations in this event.
GroupCreateEvent
Fired when a new group is being created.
java
import dev.hyperperms.api.event.GroupCreateEvent;
@EventHandler
public void onGroupCreate(GroupCreateEvent event) {
String groupName = event.getGroupName();
// Prevent creation of certain groups
if (groupName.startsWith("reserved_")) {
event.setCancelled(true);
event.setCancelReason("Cannot create groups with 'reserved_' prefix");
return;
}
getLogger().info("Group created: " + groupName);
}GroupDeleteEvent
Fired when a group is being deleted.
java
import dev.hyperperms.api.event.GroupDeleteEvent;
@EventHandler
public void onGroupDelete(GroupDeleteEvent event) {
Group group = event.getGroup();
// Prevent deletion of protected groups
if (group.getName().equals("default")) {
event.setCancelled(true);
event.setCancelReason("Cannot delete the default group");
return;
}
// Log the deletion
getLogger().info("Group deleted: " + group.getName());
}GroupModifyEvent
Fired when a group's properties or permissions are modified.
java
import dev.hyperperms.api.event.GroupModifyEvent;
import dev.hyperperms.api.event.GroupModifyEvent.ModificationType;
@EventHandler
public void onGroupModify(GroupModifyEvent event) {
Group group = event.getGroup();
ModificationType type = event.getModificationType();
switch (type) {
case PERMISSION_ADD:
getLogger().info("Permission added to " + group.getName());
break;
case PERMISSION_REMOVE:
getLogger().info("Permission removed from " + group.getName());
break;
case PARENT_ADD:
getLogger().info("Parent added to " + group.getName());
break;
case PARENT_REMOVE:
getLogger().info("Parent removed from " + group.getName());
break;
case WEIGHT_CHANGE:
getLogger().info("Weight changed for " + group.getName());
break;
case PREFIX_CHANGE:
getLogger().info("Prefix changed for " + group.getName());
break;
case SUFFIX_CHANGE:
getLogger().info("Suffix changed for " + group.getName());
break;
}
}UserModifyEvent
Fired when a user's permissions, groups, or properties are modified.
java
import dev.hyperperms.api.event.UserModifyEvent;
import dev.hyperperms.api.event.UserModifyEvent.ModificationType;
@EventHandler
public void onUserModify(UserModifyEvent event) {
User user = event.getUser();
ModificationType type = event.getModificationType();
switch (type) {
case GROUP_ADD:
Group addedGroup = (Group) event.getData();
getLogger().info(user.getUsername() + " added to " + addedGroup.getName());
break;
case GROUP_REMOVE:
Group removedGroup = (Group) event.getData();
getLogger().info(user.getUsername() + " removed from " + removedGroup.getName());
break;
case PRIMARY_GROUP_CHANGE:
Group newPrimary = (Group) event.getData();
getLogger().info(user.getUsername() + " primary group set to " + newPrimary.getName());
break;
case PERMISSION_ADD:
case PERMISSION_REMOVE:
getLogger().info(user.getUsername() + " permissions modified");
break;
}
}UserPromoteEvent
Fired when a user is promoted on a track.
java
import dev.hyperperms.api.event.UserPromoteEvent;
@EventHandler
public void onUserPromote(UserPromoteEvent event) {
User user = event.getUser();
Track track = event.getTrack();
Group fromGroup = event.getFromGroup();
Group toGroup = event.getToGroup();
getLogger().info(String.format(
"%s promoted from %s to %s on track %s",
user.getUsername(),
fromGroup.getName(),
toGroup.getName(),
track.getName()
));
// Example: Send a message to the player
Player player = Bukkit.getPlayer(user.getUuid());
if (player != null) {
player.sendMessage("Congratulations! You've been promoted to " + toGroup.getDisplayName());
}
}UserDemoteEvent
Fired when a user is demoted on a track.
java
import dev.hyperperms.api.event.UserDemoteEvent;
@EventHandler
public void onUserDemote(UserDemoteEvent event) {
User user = event.getUser();
Track track = event.getTrack();
Group fromGroup = event.getFromGroup();
Group toGroup = event.getToGroup();
getLogger().info(String.format(
"%s demoted from %s to %s on track %s",
user.getUsername(),
fromGroup.getName(),
toGroup.getName(),
track.getName()
));
}Event Priority
Use event priorities to control the order in which listeners are called:
java
import org.bukkit.event.EventPriority;
// Called early - good for logging
@EventHandler(priority = EventPriority.LOWEST)
public void onPermissionCheckLog(PermissionCheckEvent event) {
// Log the original result
}
// Called late - good for overriding
@EventHandler(priority = EventPriority.HIGHEST)
public void onPermissionCheckOverride(PermissionCheckEvent event) {
// Override the result if needed
}Cancelling Events
Cancellable events can be cancelled to prevent the action:
java
@EventHandler
public void onGroupDelete(GroupDeleteEvent event) {
// Prevent deletion
event.setCancelled(true);
// Optionally provide a reason (shown to command executor)
event.setCancelReason("Group deletion is disabled");
}When an event is cancelled, the action is prevented but the source (command or API call) will receive notification that it was cancelled.
Registering Listeners
java
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
// Register your event listeners
getServer().getPluginManager().registerEvents(
new PermissionListener(),
this
);
}
}Best Practices
- Keep handlers fast - Especially for PermissionCheckEvent
- Use appropriate priority - Log early, modify late
- Don't block - Avoid I/O or network calls in handlers
- Handle exceptions - Don't let errors propagate
- Be careful cancelling - Consider the user experience