Permission System
Detailní dokumentace permission systému v Hytale.
---
Přehled
Hytale používá hierarchický permission systém s podporou:
- Uživatelských oprávnění
- Skupinových oprávnění
- Wildcards (
,.) - Negací (
-permission) - Virtual groups (dynamické skupiny)
---
HytalePermissions
Z Dekompilovaného Kódu
public class HytalePermissions {
public static final String NAMESPACE = "hytale";
public static final String COMMAND_BASE = "hytale.command"; // Předdefinovaná oprávnění
public static final String ASSET_EDITOR = "hytale.editor.asset";
public static final String ASSET_EDITOR_PACKS_CREATE = "hytale.editor.packs.create";
public static final String ASSET_EDITOR_PACKS_EDIT = "hytale.editor.packs.edit";
public static final String ASSET_EDITOR_PACKS_DELETE = "hytale.editor.packs.delete";
public static final String BUILDER_TOOLS_EDITOR = "hytale.editor.builderTools";
public static final String EDITOR_BRUSH_USE = "hytale.editor.brush.use";
public static final String EDITOR_BRUSH_CONFIG = "hytale.editor.brush.config";
public static final String EDITOR_PREFAB_USE = "hytale.editor.prefab.use";
public static final String EDITOR_PREFAB_MANAGE = "hytale.editor.prefab.manage";
public static final String EDITOR_SELECTION_USE = "hytale.editor.selection.use";
public static final String EDITOR_SELECTION_CLIPBOARD = "hytale.editor.selection.clipboard";
public static final String EDITOR_SELECTION_MODIFY = "hytale.editor.selection.modify";
public static final String EDITOR_HISTORY = "hytale.editor.history";
public static final String FLY_CAM = "hytale.camera.flycam";
// Factory metody
@Nonnull
public static String fromCommand(@Nonnull String name) {
return "hytale.command." + name;
}
@Nonnull
public static String fromCommand(@Nonnull String name, @Nonnull String subCommand) {
return "hytale.command." + name + "." + subCommand;
}
}
Vytváření Oprávnění
// Pro příkazy (s automatickým prefixem)
String perm1 = HytalePermissions.fromCommand("spawn");
// Výsledek: "hytale.command.spawn"String perm2 = HytalePermissions.fromCommand("spawn", "self");
// Výsledek: "hytale.command.spawn.self"
// Vlastní oprávnění (vlastní namespace)
String perm3 = "myplugin.admin";
String perm4 = "myplugin.command.warp.set";
---
PermissionsModule
Singleton Přístup
PermissionsModule perms = PermissionsModule.get();
Kontrola Oprávnění
UUID playerUuid = playerRef.getUuid();// Základní kontrola
boolean hasPerm = perms.hasPermission(playerUuid, "hytale.command.spawn");
// S výchozí hodnotou
boolean hasPermDef = perms.hasPermission(playerUuid, "myplugin.special", false);
Z Dekompilovaného Kódu - hasPermission()
public boolean hasPermission(@Nonnull UUID uuid, @Nonnull String id, boolean def) {
for (PermissionProvider permissionProvider : this.providers) {
// 1. Kontrola uživatelských oprávnění
Set userNodes = permissionProvider.getUserPermissions(uuid);
Boolean userHasPerm = hasPermission(userNodes, id);
if (userHasPerm != null) {
return userHasPerm;
} // 2. Kontrola skupinových oprávnění
for (String group : permissionProvider.getGroupsForUser(uuid)) {
Set groupNodes = permissionProvider.getGroupPermissions(group);
Boolean groupHasPerm = hasPermission(groupNodes, id);
if (groupHasPerm != null) {
return groupHasPerm;
}
// 3. Kontrola virtuálních skupin
Set virtualNodes = this.virtualGroups.get(group);
Boolean virtualHasPerm = hasPermission(virtualNodes, id);
if (virtualHasPerm != null) {
return virtualHasPerm;
}
}
}
return def; // Výchozí hodnota
}
---
Permission Matching
Logika Kontroly
@Nullable
public static Boolean hasPermission(@Nullable Set nodes, @Nonnull String id) {
if (nodes == null) {
return null;
} // Wildcard * - všechna oprávnění
if (nodes.contains("*")) {
return Boolean.TRUE;
}
// Negace -* - žádná oprávnění
if (nodes.contains("-*")) {
return Boolean.FALSE;
}
// Přesná shoda
if (nodes.contains(id)) {
return Boolean.TRUE;
}
// Negace konkrétního oprávnění
if (nodes.contains("-" + id)) {
return Boolean.FALSE;
}
// Hierarchická kontrola (např. "hytale.command.*")
String[] split = id.split("\\.");
StringBuilder completeTrace = new StringBuilder();
for (int i = 0; i < split.length; i++) {
if (i > 0) {
completeTrace.append('.');
}
completeTrace.append(split[i]);
// Wildcard na této úrovni
if (nodes.contains(completeTrace + ".*")) {
return Boolean.TRUE;
}
// Negace wildcard na této úrovni
if (nodes.contains("-" + completeTrace.toString() + ".*")) {
return Boolean.FALSE;
}
}
return null; // Není definováno
}
Příklady Matching
| Node v Setu | Kontrolované ID | Výsledek |
|-------------|-----------------|----------|
| * | jakékoliv | true |
| -* | jakékoliv | false |
| hytale.command.spawn | hytale.command.spawn | true |
| -hytale.command.spawn | hytale.command.spawn | false |
| hytale.command.* | hytale.command.spawn | true |
| hytale.* | hytale.command.spawn | true |
| -hytale.command.* | hytale.command.spawn | false |
---
Správa Oprávnění
Uživatelská Oprávnění
PermissionsModule perms = PermissionsModule.get();
UUID uuid = playerRef.getUuid();// Přidání oprávnění
perms.addUserPermission(uuid, Set.of("myplugin.admin"));
// Odebrání oprávnění
perms.removeUserPermission(uuid, Set.of("myplugin.admin"));
Skupinová Oprávnění
// Přidání oprávnění skupině
perms.addGroupPermission("moderators", Set.of("myplugin.moderate.*"));// Odebrání oprávnění ze skupiny
perms.removeGroupPermission("moderators", Set.of("myplugin.moderate.kick"));
Správa Skupin Uživatelů
UUID uuid = playerRef.getUuid();// Přidání do skupiny
perms.addUserToGroup(uuid, "vip");
// Odebrání ze skupiny
perms.removeUserFromGroup(uuid, "vip");
// Získání skupin uživatele
Set groups = perms.getGroupsForUser(uuid);
---
Virtual Groups
Dynamické skupiny přiřazené na základě stavu (např. GameMode).
// Z PermissionsModule.start()
Map> virtualGroups = CommandManager.get().createVirtualPermissionGroups();// Creative mode má automaticky builder tools
virtualGroups.computeIfAbsent(GameMode.Creative.toString(), k -> new HashSet<>())
.add("hytale.editor.builderTools");
this.setVirtualGroups(virtualGroups);
Nastavení Virtual Groups
Map> myVirtualGroups = new HashMap<>();// Hráči v Creative modu mají tyto oprávnění
myVirtualGroups.put("Creative", Set.of(
"myplugin.creative.fly",
"myplugin.creative.build"
));
// Hráči v Adventure modu mají jiná oprávnění
myVirtualGroups.put("Adventure", Set.of(
"myplugin.adventure.quest"
));
perms.setVirtualGroups(myVirtualGroups);
---
PermissionProvider Interface
Pro vlastní implementace permission systému.
public interface PermissionProvider {
@Nonnull
String getName(); // Uživatelská oprávnění
void addUserPermissions(@Nonnull UUID uuid, @Nonnull Set permissions);
void removeUserPermissions(@Nonnull UUID uuid, @Nonnull Set permissions);
Set getUserPermissions(@Nonnull UUID uuid);
// Skupinová oprávnění
void addGroupPermissions(@Nonnull String group, @Nonnull Set permissions);
void removeGroupPermissions(@Nonnull String group, @Nonnull Set permissions);
Set getGroupPermissions(@Nonnull String group);
// Správa skupin
void addUserToGroup(@Nonnull UUID uuid, @Nonnull String group);
void removeUserFromGroup(@Nonnull UUID uuid, @Nonnull String group);
Set getGroupsForUser(@Nonnull UUID uuid);
}
Vlastní Provider
public class MyPermissionProvider implements PermissionProvider {
private final Map> userPermissions = new ConcurrentHashMap<>();
private final Map> groupPermissions = new ConcurrentHashMap<>();
private final Map> userGroups = new ConcurrentHashMap<>(); @Override
public String getName() {
return "MyPlugin Permissions";
}
@Override
public void addUserPermissions(UUID uuid, Set permissions) {
userPermissions.computeIfAbsent(uuid, k -> new HashSet<>()).addAll(permissions);
}
@Override
public Set getUserPermissions(UUID uuid) {
return userPermissions.getOrDefault(uuid, Collections.emptySet());
}
// ... další metody
}
Registrace Providera
@Override
protected void setup() {
PermissionsModule.get().addProvider(new MyPermissionProvider());
}@Override
protected void shutdown() {
PermissionsModule.get().removeProvider(myProvider);
}
---
PermissionHolder Interface
Pro objekty které mohou mít oprávnění.
public interface PermissionHolder {
boolean hasPermission(@Nonnull String permission);
boolean hasPermission(@Nonnull String permission, boolean defaultValue);
}
Implementace (PlayerRef)
PlayerRef implementuje PermissionHolder:
PlayerRef playerRef = ...;if (playerRef.hasPermission("myplugin.admin")) {
// Má oprávnění
}
// S výchozí hodnotou
boolean canEdit = playerRef.hasPermission("myplugin.edit", false);
---
Pořadí Priority
1. Uživatelské oprávnění (nejnižší číslo = nejvyšší priorita)
↓
2. Skupinové oprávnění (podle pořadí skupin)
↓
3. Virtual group oprávnění
↓
4. Výchozí hodnota
Při negaci (-permission) se kontrola zastaví a vrátí false.
---
Shrnutí
| Operace | Metoda |
|---------|--------|
| Kontrola oprávnění | PermissionsModule.get().hasPermission(uuid, perm) |
| Přidání user perm | addUserPermission(uuid, Set.of(...)) |
| Odebrání user perm | removeUserPermission(uuid, Set.of(...)) |
| Přidání do skupiny | addUserToGroup(uuid, groupName) |
| Odebrání ze skupiny | removeUserFromGroup(uuid, groupName) |
| Skupiny uživatele | getGroupsForUser(uuid) |
| Registrace providera | addProvider(provider) |
| Pattern | Význam |
|---------|--------|
| * | Všechna oprávnění |
| -* | Žádná oprávnění |
| hytale.command.* | Všechny příkazy |
| -hytale.command.spawn | Negace konkrétního |
| myplugin.* | Všechna oprávnění pluginu |