HyCodeYourTale

Permission System

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 |

Last updated: 20. ledna 2026