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

EventFired WhenCancellable
PermissionCheckEventA permission is checkedNo (result modifiable)
GroupCreateEventA group is createdYes
GroupDeleteEventA group is deletedYes
GroupModifyEventA group is modifiedYes
UserModifyEventUser data is modifiedYes
UserPromoteEventUser is promoted on a trackYes
UserDemoteEventUser is demoted on a trackYes

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 checked
  • getPermission() - The permission node being checked
  • getContexts() - The contexts for this check
  • getResult() - The calculated result
  • setResult(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

See Also