Depuis la 1.11, Forge a rajouté un package nommé net.minecraftforge.server.permission contenant la classe PermissionAPI qui permet désormais de
gérer les permissions avec un système interne à Forge.
Le concept est le suivant: les mods enregistrent des permissions (appelées Nodes) via
PermissionAPI#registerNode puis, lorsque qu’ils ont besoin de vérifier si un joueur a une permission, ils n’ont qu’utiliser la fonction
PermissionAPI#hasPermission.
Pour gérer tout ceci, Forge a besoin d’une classe implémentant l’interface IPermissionHandler, il n’y a qu’une et qu’une seule classe qui peut gérer
les permissions. Forge met à disposition sa propre classe appelée DefaultPermissionHandler, cependant elle n’est pas très complète et c’est, je pense,
voulu de la part des développeurs de Forge. Cette classe peut être changée en utilisant PermissionAPI#setPermissionHandler.
Dans ce tutoriel nous aborderons tout d’abord la façon d’enregistrer les nodes et de vérifier si un joueur a une permission, puis nous nous intéresserons
à la façon de créer son propre système.
Il n’y a aucun pré-requis à ce tutoriel.
Enregistrer ses permissions
Pour enregistrer vos permissions, il faut appeler la fonction PermissionAPI#registerNode après la phase de pre-initialisation, c’est très important.
La fonction prend 3 paramètres :
- Le nom de la node (String) : c’est le nom de votre permission, elle doit être du format modid.subgroup.permission_id, ce n’est pas obligatoire mais
c’est le format recommandé par Forge. Attention, les nodes sont sensibles à la casse (a != A).
- Le niveau de permission par défaut (DefaultPermissionLevel) : cela sert à définir qui a cette permission (par défaut), les valeurs possibles sont ALL, OP, NONE, elles font partie de l’enum DefaultPermissionLevel.
- La description (String) : cet argument vous sert à décrire à quoi sert votre permission.
Attention : aucun de ces arguments ne peut être null.
Exemple d’enregistrement d’une permission fictive :
| @EventHandler |
| public void init(FMLInitializationEvent event) |
| { |
| PermissionAPI.registerNode("mfftuto.items.laser", DefaultPermissionLevel.OP, "Donne accès à l'utilisation du pistolet laser"); |
| } |
Voilà, c’est tout pour l’enregistrement des permissions.
Vérifier si un joueur a une permission
Une fois vos permissions enregistrées, vous pouvez à tout moment appeler la fonction PermissionAPI#hasPermission pour savoir si le joueur passé en
argument a la permission donnée.
La fonction prend deux arguments :
- Le joueur (EntityPlayer) : le joueur que vous voulez tester.
- La node (String) : la permission à tester.
Exemple fictif :
| public ActionResult <itemstack>onItemRightClick(World world, EntityPlayer player, EnumHand hand) |
| { |
| if(PermissionAPI.hasPermission(player, "mfftuto.items.laser")) { |
| |
| |
| return new ActionResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); |
| } |
| return new ActionResult(EnumActionResult.PASS, player.getHeldItem(hand)); |
| } |
On peut aussi utiliser un autre prototype de la fonction :
public static boolean hasPermission(GameProfile profile, String node, @Nullable IContext context)
L’instance du GameProfile peut-être récupérée depuis l’instance du joueur avec :
player.getGameProfile();
La node est votre permission.
Le IContext est un context dans lequel se trouve le joueur, il en existe plusieurs créés par Forge :
- AreaContext
- BlockPosContext
- PlayerContext
- TargetContext
- WorldContext
Je ne parlerai pas des ContextKey car je n’ai pas encore totalement assimilé le fonctionnement.
Cet argument sera passé à la classe implémentant l’interface IPermissionHandler afin qu’il puisse l’utiliser pour savoir si le joueur possède la permission donnée.
Exemple :
| public ActionResult <itemstack>onItemRightClick(World world, EntityPlayer player, EnumHand hand) |
| { |
| if(PermissionAPI.hasPermission(player, "mfftuto.items.laser", new WorldContext(world))) { |
| |
| |
| return new ActionResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); |
| } |
| return new ActionResult(EnumActionResult.PASS, player.getHeldItem(hand)); |
| } |
Les contexts ne sont pas utilisés par la classe DefaultPermissionHandler de Forge mais, comme dit dans l’introduction, je ne pense pas que cette API soit
faite pour que l’on garde la classe de base. Deuxième information, la fonction PermissionAPI#hasPermission(EntityPlayer player, String node) crée un PlayerContext.
Créer sa propre implémentation de IPermissionHandle
L’interface IPermissionHandler vous permet de créer votre propre système pour gérer les permissions.
Premièrement il vous faut créer une classe implémentant cette interface :
| public class CustomPermissionHandler implements IPermissionHandler { |
| |
| @Override |
| public void registerNode(String node, DefaultPermissionLevel level, String desc) { |
| |
| } |
| |
| @Override |
| public Collection <string>getRegisteredNodes() { |
| return null; |
| } |
| |
| @Override |
| public boolean hasPermission(GameProfile profile, String node, IContext context) { |
| return false; |
| } |
| |
| @Override |
| public String getNodeDescription(String node) { |
| return null; |
| } |
| } |
Dans cette classe, la fonction registerNode sera appelée à chaque fois qu’un mod va enregistrer une permission.
La fonction getRegisteredNodes doit renvoyer toutes les permissions enregistrées.
La fonction hasPermission doit renvoyer si oui ou non le joueur a la permission donnée.
Et la fonction getNodeDescription doit renvoyer la description de la permission donnée.
Je ne vais pas vous faire d’exemple ici, vous pouvez regarder comment gère tout ceci Forge dans la classe DefaultPermissionHandler mais
le but ici est de faire votre propre système.
Il vous faudra ensuite définir votre classe comme PermissionHandler durant la phase de pre-initialisation :
| @EventHandler |
| public void preInit(FMLPreInitializationEvent event) |
| { |
| PermissionAPI.setPermissionHandler(new CustomPermissionHandler()); |
| } |
Et c’est tout. Merci d’avoir lu, mettez un pouce bleu et n’hésitez pas à partager :troll: 