Ranks & Permissions
Ranks & Permissions
Ranks carry a name, a priority, prefix/suffix formatting, and a permission set that can inherit from other ranks. Players receive ranks through grants, and permission checks resolve to a three-state model (allowed, denied, or undefined).
Getting the manager
RankManager ranks = VoxyAPI.getAPI().getRankManager();
RankManager operations are synchronous. Methods such as updateRank, deleteRank, and createRank persist to the database and publish packets to other servers as part of the call.
Looking up ranks
Fetch a rank by name or UUID. Both overloads are annotated @Nullable and return null when no rank matches, so guard the result:
Rank admin = ranks.getRank("Admin"); // may be null
if (admin == null) {
getLogger().warning("No 'Admin' rank exists.");
return;
}
Rank byId = ranks.getRank(admin.getID()); // by UUID
The default rank is always available and never null:
Rank def = ranks.getDefaultRank();
List ranks in a few useful orders. Each of these returns a Collection<Rank>, except getRankNamesArray which returns a String[]:
Collection<Rank> all = ranks.getRanks();
Collection<Rank> ascending = ranks.getSortedRanks(); // by priority, ascending
Collection<Rank> descending = ranks.getReversedRanks(); // by priority, descending
String[] names = ranks.getRankNamesArray();
Reading rank properties
Rank is an interface (it extends Comparable<Rank>). The properties it exposes:
UUID id = rank.getID();
String name = rank.getName();
int priority = rank.getPriority();
String prefix = rank.getPrefix();
String suffix = rank.getSuffix();
// Adventure-formatted variants
Component adventurePrefix = rank.getAdventurePrefix();
Component adventureSuffix = rank.getAdventureSuffix();
Component coloredName = rank.getAdventureColoredName();
TextColor color = rank.getColor();
Useful flags include isDefaulted(), isStaff(), isReachable(), isAuth(), and isForceAuth(), plus getFriendLimit() (where -1 means unlimited) and getDiscordRoleID().
Inheritance
A rank inherits from other ranks referenced by their UUIDs. getInheritedRanks() returns a Set<UUID>:
Set<UUID> parents = rank.getInheritedRanks();
for (UUID parentId : parents) {
Rank parent = ranks.getRank(parentId);
}
Permissions on a rank
A rank holds its own permission set plus pre-computed caches that already fold in inherited ranks. getPermissions() returns a Set<Permission>, while the cached views return a Set<String>:
Set<Permission> own = rank.getPermissions(); // this rank's own entries
Set<String> effective = rank.getCachedPermissions(); // resolved, including inheritance
Set<String> negated = rank.getCachedNegatedPermissions(); // resolved negations
A Permission is a record of a permission value and a Duration:
public record Permission(String value, Duration duration) { }
Its value is stored lowercased, and hasExpired() reports whether the permission's duration has elapsed:
for (Permission permission : rank.getPermissions()) {
if (!permission.hasExpired()) {
getLogger().info("Active permission: " + permission.value());
}
}
Check a permission against a rank directly:
boolean can = rank.hasPermission("voxy.admin.manage.users");
Player rank grants
A Grant ties a rank to a player for a duration, with metadata about who issued it and where it applies. Grants are read-only from a player's PlayerData (obtained through the DataManager, see Player Data):
PlayerData data = VoxyAPI.getAPI().getDataManager()
.getOrLoad(playerId)
.orElse(null);
if (data != null) {
for (Grant grant : data.getGrants()) {
if (grant.isValid()) {
Rank granted = grant.getRank(); // resolves via RankManager; null if the rank was deleted
getLogger().info(data.getName() + " has " + granted.getName()
+ " (by " + grant.getBy() + ")");
}
}
}
Grant exposes:
UUID getRankID(); // the granted rank's UUID
Rank getRank(); // resolved Rank, or null if it no longer exists
Duration getDuration(); // how long the grant lasts
String getBy(); // who issued it (default "CONSOLE")
String getServers(); // where it applies (default "ALL")
String getReason();
boolean isRevoked();
boolean isValid(); // true when the rank exists, is not revoked, and has not expired
A player's active rank is derived from valid grants. PlayerData exposes getRank() and getCurrentRank(), and calculateHighestRank() recomputes the highest-priority granted rank.
Permission state model
Permissions resolve to a three-state enum rather than a simple boolean:
public enum PermissionState { ALLOWED, DENIED, UNDEFINED; }
ALLOWED- a matching node or wildcard grants the permission.DENIED- a node in the tree is explicitly negated.UNDEFINED- nothing matches, so a caller can fall through to a default.
PermissionState has a helper to collapse it to a boolean with your chosen default for the undefined case:
PermissionState state = rank.permissionState("voxy.admin.manage.users");
boolean allowed = state.toBoolean(false); // UNDEFINED -> false here
Both Rank and PlayerData provide permissionState(String) and boolean hasPermission(String) checks. Use permissionState when the difference between an explicit denial and an unmatched node matters; use hasPermission for a plain yes/no:
if (data.hasPermission("voxy.admin.manage.users")) {
// ...
}
// Or with a default-permission flag:
boolean can = rank.hasPermission("voxy.chat.color", true);
Key methods
| Signature | Description |
|---|---|
Rank getRank(String name) |
Looks up a rank by name; null if none. |
Rank getRank(UUID uuid) |
Looks up a rank by UUID; null if none. |
Rank getDefaultRank() |
The default rank; never null. |
Collection<Rank> getRanks() |
All ranks. |
Collection<Rank> getSortedRanks() |
Ranks by priority, ascending. |
Collection<Rank> getReversedRanks() |
Ranks by priority, descending. |
String[] getRankNamesArray() |
Array of all rank names. |
void createRank(String name) |
Creates and persists a new rank. |
void updateRank(Rank rank) |
Persists a rank and publishes an update packet. |
void deleteRank(Rank rank, boolean internal) |
Deletes a rank; internal skips database removal. |
Set<Permission> Rank.getPermissions() |
The rank's own permission entries. |
Set<String> Rank.getCachedPermissions() |
Resolved permissions including inheritance. |
Set<UUID> Rank.getInheritedRanks() |
UUIDs of inherited ranks. |
PermissionState Rank.permissionState(String permission) |
Three-state resolution for a node. |
boolean Rank.hasPermission(String permission) |
Plain yes/no permission check. |
Collection<Grant> PlayerData.getGrants() |
All rank grants assigned to a player. |
Rank Grant.getRank() |
Resolves the granted rank; null if deleted. |
boolean Grant.isValid() |
True when the grant is active (exists, not revoked, not expired). |
boolean PermissionState.toBoolean(boolean def) |
Collapses the state to a boolean, using def for UNDEFINED. |