Developer API

HyperPerms provides a Java API for plugin developers to check permissions, manage groups, and integrate with the permission system programmatically.

Getting Started

Adding the Dependency

Add HyperPerms as a dependency in your project via JitPack:

Maven

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.HyperSystemsDev</groupId>
    <artifactId>HyperPerms</artifactId>
    <version>v2.8.6</version>
    <scope>provided</scope>
</dependency>

Gradle

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    compileOnly 'com.github.HyperSystemsDev:HyperPerms:v2.8.6'
}

Plugin Dependency

Add HyperPerms as a dependency in your plugin.yml:

name: MyPlugin
version: 1.0.0
main: com.example.MyPlugin
depend: [HyperPerms]

Accessing the API

Getting the API Instance

import com.hyperperms.api.HyperPermsAPI;
import com.hyperperms.HyperPerms;

public class MyPlugin extends JavaPlugin {

    private HyperPermsAPI hyperPerms;

    @Override
    public void onEnable() {
        // Get the API instance
        hyperPerms = HyperPerms.getApi();

        if (hyperPerms == null) {
            getLogger().severe("HyperPerms not found!");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }

        getLogger().info("HyperPerms API loaded successfully!");
    }
}

Checking Permissions

Fluent Permission Check Builder

HyperPerms provides a fluent API for building permission checks with contexts:

import com.hyperperms.HyperPerms;

// Simple permission check
boolean canFly = HyperPerms.getInstance()
    .check(playerUuid)
    .permission("fly.enable")
    .result();

// Permission check with world context
boolean canBuild = HyperPerms.getInstance()
    .check(playerUuid)
    .permission("build.place")
    .inWorld("nether")
    .result();

// Permission check with multiple contexts
boolean canPvP = HyperPerms.getInstance()
    .check(playerUuid)
    .permission("pvp.enable")
    .inWorld("arena")
    .withGamemode("survival")
    .result();

// Custom context
boolean hasAccess = HyperPerms.getInstance()
    .check(playerUuid)
    .permission("region.access")
    .withContext("region", "spawn")
    .result();

Builder Methods

MethodDescription
.permission(String)Set the permission to check (required)
.inWorld(String)Add world context
.withGamemode(String)Add gamemode context
.withContext(String, String)Add any custom context key-value pair
.result()Execute the check and return boolean
.hasAny(String...)Check if any of the listed permissions are granted
.hasAll(String...)Check if all of the listed permissions are granted

Checking Multiple Permissions

// Check if player has ANY of these permissions
boolean canModerate = HyperPerms.getInstance()
    .check(playerUuid)
    .hasAny("mod.kick", "mod.ban", "mod.mute");

// Check if player has ALL of these permissions
boolean isFullAdmin = HyperPerms.getInstance()
    .check(playerUuid)
    .hasAll("admin.users", "admin.groups", "admin.config");

Basic Permission Check

import com.hyperperms.api.model.User;
import java.util.UUID;

// Check if a player has a permission
public boolean checkPermission(UUID playerUuid, String permission) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user == null) {
        return false;
    }

    return user.hasPermission(permission);
}

Permission Check with Context

import com.hyperperms.api.context.ContextSet;

// Check permission with specific context
public boolean checkPermissionInWorld(UUID playerUuid, String permission, String world) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user == null) {
        return false;
    }

    ContextSet contexts = ContextSet.builder()
        .add("world", world)
        .build();

    return user.hasPermission(permission, contexts);
}

Getting Permission Value

import com.hyperperms.api.model.PermissionResult;

// Get detailed permission result
public void checkPermissionDetail(UUID playerUuid, String permission) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user == null) {
        return;
    }

    PermissionResult result = user.getPermissionValue(permission);

    System.out.println("Permission: " + permission);
    System.out.println("Value: " + result.getValue());
    System.out.println("Source: " + result.getSource());
    System.out.println("Is Set: " + result.isSet());
}

Async Permission Checking

For non-blocking permission checks, use the async methods that return CompletableFuture:

Async Methods

import java.util.concurrent.CompletableFuture;

// Async permission check
CompletableFuture<Boolean> future = hyperPerms.getUserManager()
    .loadUser(playerUuid)
    .thenApply(user -> user.hasPermissionAsync("some.permission"));

future.thenAccept(result -> {
    System.out.println("Has permission: " + result);
});

Async Detailed Permission Value

// Async detailed permission value
hyperPerms.getUserManager().loadUser(playerUuid).thenAccept(user -> {
    CompletableFuture<PermissionResult> result = user.getPermissionValueAsync("some.permission");
    result.thenAccept(r -> {
        System.out.println("Value: " + r.getValue());
        System.out.println("Source: " + r.getSource());
    });
});

Fluent checkAsync Builder

// Fluent async check with context
hyperPerms.checkAsync(playerUuid)
    .permission("build.place")
    .withContext("world", "creative")
    .withContext("gamemode", "creative")
    .check()
    .thenAccept(result -> {
        System.out.println("Can build: " + result);
    });

// Check multiple permissions asynchronously
api.checkAsync(uuid)
   .hasAny("mod.kick", "mod.ban", "mod.mute")
   .thenAccept(canModerate -> { });

TriState Enum

The TriState enum distinguishes between explicitly granted, explicitly denied, and undefined permissions:

import com.hyperperms.api.TriState;

TriState value = api.getPermissionValue(uuid, "some.permission");

switch (value) {
    case TRUE -> // Explicitly granted
    case FALSE -> // Explicitly denied
    case UNDEFINED -> // Not set (inherits default)
}

This is useful when you need to know whether a permission was explicitly set versus simply not defined. For example:

  • TRUE - The permission was explicitly granted
  • FALSE - The permission was explicitly denied (negated)
  • UNDEFINED - No permission node exists; use your plugin's default behavior

Temporary Permissions API

Set permissions that automatically expire after a duration. Available since v2.8.2.

setTemporaryPermission

import com.hyperperms.api.model.Node;
import java.time.Duration;

// Add a temporary permission (expires in 1 hour)
User user = hyperPerms.getUserManager().getUser(playerUuid);

if (user != null) {
    Node tempNode = Node.builder("vip.fly")
        .withValue(true)
        .withExpiry(Duration.ofHours(1))
        .build();

    user.addPermission(tempNode);
    hyperPerms.getUserManager().saveUser(user);
}

Duration Syntax

Duration can be specified using standard Java Duration or parsed from string format:

// Various duration formats
Duration.ofMinutes(30);   // 30 minutes
Duration.ofHours(6);      // 6 hours
Duration.ofDays(7);       // 7 days
Duration.ofDays(30);      // 30 days

// Temporary group membership
user.addGroup(group, Duration.ofDays(30)); // 30-day VIP
hyperPerms.getUserManager().saveUser(user);

Permission Enumeration

Retrieve all resolved permissions for a user, including inherited permissions. Available since v2.8.3.

getResolvedPermissions

import com.hyperperms.api.model.ResolvedPermission;
import java.util.Set;

// Get all resolved permissions for a user
Set<ResolvedPermission> permissions = hyperPerms.getUserManager()
    .getResolvedPermissions(playerUuid);

for (ResolvedPermission perm : permissions) {
    System.out.println(String.format(
        "Permission: %s, Value: %s, Source: %s",
        perm.getPermission(),
        perm.getValue(),
        perm.getSource()
    ));
}

QueryAPI

Search and query users and groups programmatically:

QueryAPI query = api.getQuery();

// Find users with a permission
query.findUsersWithPermission("admin.*")
     .thenAccept(uuids -> { });

// Find users in a group
query.findUsersInGroup("moderator")
     .thenAccept(uuids -> { });

// Fluent user queries
query.queryUsers()
    .withPermission("build.*")
    .inGroup("builder")
    .withContext("world", "creative")
    .limit(100)
    .execute()
    .thenAccept(uuids -> { });

// Group queries
Set<String> groups = query.queryGroups()
    .withWeightBetween(50, 100)
    .inheritsFrom("default")
    .execute();

MetricsAPI

Access permission check statistics and audit logs:

MetricsAPI metrics = api.getMetrics();
if (metrics != null) {
    // Cache statistics
    CacheStats cache = metrics.getCacheStats();
    double hitRate = metrics.getCacheHitRate();

    // Permission check stats
    PermissionCheckStats stats = metrics.getCheckStats();
    long total = stats.totalChecks();
    long granted = stats.grantedCount();

    // Hotspot analysis - find most checked permissions
    metrics.getHotspots(10).thenAccept(hotspots -> {
        hotspots.forEach(h ->
            System.out.println(h.permission() + ": " + h.checkCount())
        );
    });

    // Audit log - view recent permission changes
    metrics.getRecentAuditLog(50).thenAccept(entries -> {
        entries.forEach(e ->
            System.out.println(e.timestamp() + ": " + e.action())
        );
    });
}

Bulk Operations

Efficiently handle multiple users or groups:

// Load multiple users at once
api.getUserManager().loadUsers(uuidCollection)
   .thenAccept(userMap -> { });

// Save multiple users
api.getUserManager().saveUsers(userCollection);

// Batch modify users
api.getUserManager().batchModify(uuids, user -> {
    user.addNode(Node.builder("new.permission").build());
});

// Get all known UUIDs from storage
api.getUserManager().getAllKnownUUIDs()
   .thenAccept(allUuids -> { });

Managing Groups

Getting Player Groups

import com.hyperperms.api.model.Group;
import java.util.Set;

// Get all groups a player belongs to
public Set<Group> getPlayerGroups(UUID playerUuid) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user == null) {
        return Set.of();
    }

    return user.getGroups();
}

// Get primary group
public Group getPrimaryGroup(UUID playerUuid) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user == null) {
        return null;
    }

    return user.getPrimaryGroup();
}

Modifying Player Groups

// Add player to a group
public void addToGroup(UUID playerUuid, String groupName) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);
    Group group = hyperPerms.getGroupManager().getGroup(groupName);

    if (user != null && group != null) {
        user.addGroup(group);
        hyperPerms.getUserManager().saveUser(user);
    }
}

// Remove player from a group
public void removeFromGroup(UUID playerUuid, String groupName) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);
    Group group = hyperPerms.getGroupManager().getGroup(groupName);

    if (user != null && group != null) {
        user.removeGroup(group);
        hyperPerms.getUserManager().saveUser(user);
    }
}

// Set primary group
public void setPrimaryGroup(UUID playerUuid, String groupName) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);
    Group group = hyperPerms.getGroupManager().getGroup(groupName);

    if (user != null && group != null) {
        user.setPrimaryGroup(group);
        hyperPerms.getUserManager().saveUser(user);
    }
}

Working with Groups

// Get a group by name
public Group getGroup(String name) {
    return hyperPerms.getGroupManager().getGroup(name);
}

// Get all groups
public Set<Group> getAllGroups() {
    return hyperPerms.getGroupManager().getGroups();
}

// Create a new group
public Group createGroup(String name) {
    return hyperPerms.getGroupManager().createGroup(name);
}

// Check if a group exists
public boolean groupExists(String name) {
    return hyperPerms.getGroupManager().getGroup(name) != null;
}

Adding and Removing Permissions

User Permissions

import com.hyperperms.api.model.Node;

// Add a permission to a user
public void addUserPermission(UUID playerUuid, String permission, boolean value) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user != null) {
        Node node = Node.builder(permission)
            .withValue(value)
            .build();

        user.addPermission(node);
        hyperPerms.getUserManager().saveUser(user);
    }
}

// Remove a permission from a user
public void removeUserPermission(UUID playerUuid, String permission) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user != null) {
        user.removePermission(permission);
        hyperPerms.getUserManager().saveUser(user);
    }
}

Group Permissions

// Add a permission to a group
public void addGroupPermission(String groupName, String permission, boolean value) {
    Group group = hyperPerms.getGroupManager().getGroup(groupName);

    if (group != null) {
        Node node = Node.builder(permission)
            .withValue(value)
            .build();

        group.addPermission(node);
        hyperPerms.getGroupManager().saveGroup(group);
    }
}

// Add a contextual permission
public void addContextualPermission(String groupName, String permission, String world) {
    Group group = hyperPerms.getGroupManager().getGroup(groupName);

    if (group != null) {
        Node node = Node.builder(permission)
            .withValue(true)
            .withContext("world", world)
            .build();

        group.addPermission(node);
        hyperPerms.getGroupManager().saveGroup(group);
    }
}

Working with Tracks

import com.hyperperms.api.model.Track;

// Get a track
public Track getTrack(String name) {
    return hyperPerms.getTrackManager().getTrack(name);
}

// Promote a player on a track
public boolean promotePlayer(UUID playerUuid, String trackName) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);
    Track track = hyperPerms.getTrackManager().getTrack(trackName);

    if (user == null || track == null) {
        return false;
    }

    return hyperPerms.getTrackManager().promote(user, track);
}

// Demote a player on a track
public boolean demotePlayer(UUID playerUuid, String trackName) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);
    Track track = hyperPerms.getTrackManager().getTrack(trackName);

    if (user == null || track == null) {
        return false;
    }

    return hyperPerms.getTrackManager().demote(user, track);
}

Prefix and Suffix

// Get player's effective prefix
public String getPlayerPrefix(UUID playerUuid) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user == null) {
        return "";
    }

    return user.getPrefix();
}

// Get player's effective suffix
public String getPlayerSuffix(UUID playerUuid) {
    User user = hyperPerms.getUserManager().getUser(playerUuid);

    if (user == null) {
        return "";
    }

    return user.getSuffix();
}

Event System

HyperPerms fires events for all major permission operations. Available events include:

  • GroupCreateEvent - When a group is created
  • GroupDeleteEvent - When a group is deleted
  • GroupModifyEvent - When a group's properties or permissions change
  • UserGroupChangeEvent - When a user is added to or removed from a group
  • UserLoadEvent - When a user's data is loaded
  • UserUnloadEvent - When a user's data is unloaded
  • DataReloadEvent - When all permission data is reloaded
  • TrackPromotionEvent - When a user is promoted on a track
  • TrackDemotionEvent - When a user is demoted on a track

For full documentation on subscribing to events, priorities, and cancellation, see the Events page.

Best Practices

Caching

Tip: HyperPerms caches permission results internally. You don't need to implement your own caching for permission checks.

Async Operations

// For bulk operations, use async methods to avoid blocking
hyperPerms.getUserManager().loadUser(playerUuid).thenAccept(user -> {
    // Process user data off the main thread
    user.addGroup(someGroup);
    hyperPerms.getUserManager().saveUser(user);
});

// Prefer async for database-heavy operations
api.checkAsync(uuid)
   .permission("expensive.check")
   .result()
   .thenAccept(result -> {
       // Handle on completion
   });

Error Handling

// Always check for null returns
User user = hyperPerms.getUserManager().getUser(playerUuid);
if (user == null) {
    // User hasn't joined before or data isn't loaded
    return;
}

Group group = hyperPerms.getGroupManager().getGroup("vip");
if (group == null) {
    // Group doesn't exist
    getLogger().warning("VIP group not found!");
    return;
}

Event Subscription

// Subscribe to events for reactive permission changes
api.getEventBus().subscribe(UserGroupChangeEvent.class, event -> {
    // React to group changes
    getLogger().info(event.getUser().getUsername() + " group changed");
});

See Also