---
title: Système de Permissions
type: docs
weight: 12
---

Le système de Permissions fournit un contrôle d'accès granulaire pour les commandes, les fonctionnalités de l'éditeur et les fonctionnalités personnalisées des plugins.

**Package:** `com.hypixel.hytale.server.core.permissions`

## Vue d'Ensemble

Hytale utilise un système de permissions avec :
- **Permissions utilisateur** - Directement assignées aux joueurs individuels
- **Permissions de groupe** - Héritées par tous les membres d'un groupe
- **Fournisseurs de permissions** - Logique personnalisée pour les permissions dynamiques

## Accéder au Module de Permissions

```java
import com.hypixel.hytale.server.core.permissions.PermissionsModule;

// Utiliser la méthode statique get() - PAS HytaleServer.get().getPermissionsModule()
PermissionsModule permissions = PermissionsModule.get();
```

## Vérifier les Permissions

```java
UUID playerUuid = player.getPlayerRef().getUuid();

// Vérifier si le joueur a la permission
boolean canEdit = permissions.hasPermission(playerUuid, "hytale.editor.asset");

// Vérifier dans le contexte de commande
if (permissions.hasPermission(ctx.sender().getUuid(), "myplugin.admin")) {
    // Logique réservée aux admins
}
```

## Permissions Utilisateur

Gérer les permissions pour les joueurs individuels :

```java
UUID playerUuid = player.getPlayerRef().getUuid();

// Ajouter des permissions
permissions.addUserPermission(playerUuid, Set.of(
    "myplugin.feature.create",
    "myplugin.feature.delete"
));

// Supprimer des permissions
permissions.removeUserPermission(playerUuid, Set.of(
    "myplugin.feature.delete"
));
```

## Permissions de Groupe

Les groupes permettent de partager des permissions entre plusieurs joueurs :

### Gérer les Groupes

```java
// Ajouter un joueur à un groupe
permissions.addUserToGroup(playerUuid, "moderators");

// Retirer un joueur d'un groupe
permissions.removeUserFromGroup(playerUuid, "moderators");

// Obtenir tous les groupes d'un joueur
Set<String> groups = permissions.getGroupsForUser(playerUuid);
```

### Événements de Permissions de Groupe

Écouter les changements de groupes en utilisant des sous-classes spécifiques :

```java
import com.hypixel.hytale.server.core.event.events.permissions.*;

// Joueur AJOUTÉ à un groupe
getEventRegistry().register(PlayerGroupEvent.Added.class, event -> {
    UUID playerUuid = event.getPlayerUuid();
    String group = event.getGroupName();  // Note: getGroupName(), PAS getGroup()
    log("Joueur a rejoint le groupe : " + group);
});

// Joueur RETIRÉ d'un groupe
getEventRegistry().register(PlayerGroupEvent.Removed.class, event -> {
    UUID playerUuid = event.getPlayerUuid();
    String group = event.getGroupName();
    log("Joueur a quitté le groupe : " + group);
});

// Permissions du groupe AJOUTÉES
getEventRegistry().register(GroupPermissionChangeEvent.Added.class, event -> {
    String group = event.getGroupName();
    Set<String> added = event.getAddedPermissions();
    log("Groupe " + group + " a reçu les permissions : " + added);
});

// Permissions du groupe RETIRÉES
getEventRegistry().register(GroupPermissionChangeEvent.Removed.class, event -> {
    String group = event.getGroupName();
    Set<String> removed = event.getRemovedPermissions();
    log("Groupe " + group + " a perdu les permissions : " + removed);
});

// Permissions du joueur AJOUTÉES
getEventRegistry().register(PlayerPermissionChangeEvent.PermissionsAdded.class, event -> {
    UUID playerUuid = event.getPlayerUuid();
    Set<String> added = event.getAddedPermissions();
});

// Permissions du joueur RETIRÉES
getEventRegistry().register(PlayerPermissionChangeEvent.PermissionsRemoved.class, event -> {
    UUID playerUuid = event.getPlayerUuid();
    Set<String> removed = event.getRemovedPermissions();
});
```

## Permissions Intégrées

Hytale inclut de nombreuses permissions intégrées :

### Permissions de Commandes

| Permission | Description |
|------------|-------------|
| `hytale.command.*` | Accès à toutes les commandes |
| `hytale.command.gamemode` | Changer de mode de jeu |
| `hytale.command.tp` | Téléportation |
| `hytale.command.give` | Donner des objets |
| `hytale.command.time` | Contrôle du temps |

### Permissions de l'Éditeur

| Permission | Description |
|------------|-------------|
| `hytale.editor.asset` | Édition des assets |
| `hytale.editor.packs.*` | Gestion des packs |
| `hytale.editor.builderTools` | Accès aux outils de construction |
| `hytale.editor.brush.*` | Outils de pinceau |
| `hytale.editor.prefab.*` | Édition des prefabs |
| `hytale.editor.selection.*` | Outils de sélection |
| `hytale.editor.history` | Historique annuler/rétablir |

### Permissions de Caméra

| Permission | Description |
|------------|-------------|
| `hytale.camera.flycam` | Mode caméra libre |

## Fournisseur de Permission Personnalisé

Implémentez `PermissionProvider` pour une logique de permission dynamique :

{{< callout type="info" >}}
**Note :** `PermissionProvider` est une interface qui fournit des ensembles de permissions, pas une simple vérification hasPermission. Le `PermissionsModule` vérifie ces ensembles.
{{< /callout >}}

```java
import com.hypixel.hytale.server.core.permissions.provider.PermissionProvider;

public class VIPPermissionProvider implements PermissionProvider {
    private final Map<UUID, Set<String>> vipPermissions = new ConcurrentHashMap<>();
    private final Map<UUID, Set<String>> vipGroups = new ConcurrentHashMap<>();

    @Override
    @Nonnull
    public String getName() {
        return "VIPPermissionProvider";
    }

    @Override
    public Set<String> getUserPermissions(@Nonnull UUID uuid) {
        // Retourner les permissions pour cet utilisateur
        // Les utilisateurs VIP reçoivent des permissions supplémentaires automatiquement
        if (isVIP(uuid)) {
            Set<String> perms = new HashSet<>(vipPermissions.getOrDefault(uuid, Collections.emptySet()));
            perms.add("vip.lounge");
            perms.add("vip.cosmetics");
            return perms;
        }
        return vipPermissions.getOrDefault(uuid, Collections.emptySet());
    }

    @Override
    public void addUserPermissions(@Nonnull UUID uuid, @Nonnull Set<String> permissions) {
        vipPermissions.computeIfAbsent(uuid, k -> new HashSet<>()).addAll(permissions);
    }

    @Override
    public void removeUserPermissions(@Nonnull UUID uuid, @Nonnull Set<String> permissions) {
        Set<String> userPerms = vipPermissions.get(uuid);
        if (userPerms != null) {
            userPerms.removeAll(permissions);
        }
    }

    @Override
    public Set<String> getGroupPermissions(@Nonnull String group) {
        return Collections.emptySet();
    }

    @Override
    public void addGroupPermissions(@Nonnull String group, @Nonnull Set<String> permissions) {}

    @Override
    public void removeGroupPermissions(@Nonnull String group, @Nonnull Set<String> permissions) {}

    @Override
    public Set<String> getGroupsForUser(@Nonnull UUID uuid) {
        return vipGroups.getOrDefault(uuid, Collections.emptySet());
    }

    @Override
    public void addUserToGroup(@Nonnull UUID uuid, @Nonnull String group) {
        vipGroups.computeIfAbsent(uuid, k -> new HashSet<>()).add(group);
    }

    @Override
    public void removeUserFromGroup(@Nonnull UUID uuid, @Nonnull String group) {
        Set<String> groups = vipGroups.get(uuid);
        if (groups != null) {
            groups.remove(group);
        }
    }

    private boolean isVIP(UUID uuid) {
        // Votre logique de vérification VIP
        return vipDatabase.contains(uuid);
    }
}
```

### Enregistrer des Fournisseurs Personnalisés

```java
@Override
public void start() {
    PermissionsModule permissions = PermissionsModule.get();
    permissions.addProvider(new VIPPermissionProvider());
}
```

## Wildcards de Permission

Les permissions supportent les correspondances avec wildcard :

```java
// Accorder toutes les permissions sous un namespace
permissions.addUserPermission(playerUuid, Set.of("myplugin.*"));

// Ceci passe maintenant :
permissions.hasPermission(playerUuid, "myplugin.anything");
permissions.hasPermission(playerUuid, "myplugin.feature.nested");
```

## Intégration des Permissions de Commandes

Les commandes vérifient automatiquement les permissions basées sur leur ID :

```java
public class AdminCommand extends AbstractCommand {

    public AdminCommand() {
        super("admin", "myplugin.commands.admin.description");
        // La vérification de permission est automatique basée sur l'enregistrement de la commande
    }

    @Override
    protected CompletableFuture<Void> execute(CommandContext ctx) {
        // Seuls les joueurs avec la permission appropriée arrivent ici
        return null;
    }
}
```

## Exemples Pratiques

### Accès Basé sur les Rôles

```java
public class RoleManager {
    private final PermissionsModule permissions;

    public RoleManager() {
        this.permissions = PermissionsModule.get();
    }

    public void promoteToModerator(UUID playerUuid) {
        permissions.addUserToGroup(playerUuid, "moderators");
        permissions.addUserPermission(playerUuid, Set.of(
            "server.kick",
            "server.mute",
            "server.warn"
        ));
    }

    public void demoteFromModerator(UUID playerUuid) {
        permissions.removeUserFromGroup(playerUuid, "moderators");
        permissions.removeUserPermission(playerUuid, Set.of(
            "server.kick",
            "server.mute",
            "server.warn"
        ));
    }

    public boolean canModerate(UUID playerUuid) {
        return permissions.getGroupsForUser(playerUuid).contains("moderators");
    }
}
```

### Verrouillage de Fonctionnalités

```java
public void useFeature(Player player, String featureName) {
    UUID uuid = player.getPlayerRef().getUuid();
    PermissionsModule perms = PermissionsModule.get();

    String permission = "myplugin.feature." + featureName;
    if (!perms.hasPermission(uuid, permission)) {
        player.sendMessage(Message.translation("error.no_permission"));
        return;
    }

    // Exécuter la fonctionnalité
    executeFeature(player, featureName);
}
```

## Bonnes Pratiques

{{< callout type="info" >}}
**Directives des Permissions :**
- Utilisez des permissions avec namespace (ex: `myplugin.feature.name`)
- Préférez les groupes pour l'accès basé sur les rôles plutôt que les permissions individuelles
- Vérifiez les permissions aux points d'entrée, pas profondément dans la logique
- Utilisez les wildcards avec parcimonie et intentionnellement
{{< /callout >}}

{{< callout type="warning" >}}
**Note de Sécurité :** Validez toujours les permissions côté serveur. Ne faites jamais confiance aux états de permission rapportés par le client.
{{< /callout >}}
