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
| Method | Description |
|---|---|
.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 grantedFALSE- 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 createdGroupDeleteEvent- When a group is deletedGroupModifyEvent- When a group's properties or permissions changeUserGroupChangeEvent- When a user is added to or removed from a groupUserLoadEvent- When a user's data is loadedUserUnloadEvent- When a user's data is unloadedDataReloadEvent- When all permission data is reloadedTrackPromotionEvent- When a user is promoted on a trackTrackDemotionEvent- 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
- Events - Listen to permission changes
- Placeholders - Integrate with other plugins
- Permission Nodes - HyperPerms' own permissions