Developper un plugin sous spigot 1.13.2 - Les commandes avec arguments

Cercus

Un modérateur chat trop mignon
Staff
Modérateur
6 Octobre 2013
791
77
152
25
Bonjour à tous, j'ai décidé de poursuivre la série de tutoriel commencé par @Plx0wn en 2016... . Dans la suite de ce tutoriel et dans les suivant, j'utiliserais la version 1.13.2 de spigot.

Dans le tutoriel d'aujourd'hui, on va voir comment créer des commandes avec des arguments.


~~~~ Bases et pré-requis ~~~~

- Connaître les bases du langage Java
- Je recommande de lire les 2 tutoriels déjà fait par @Plx0wn. Ils sont disponibles ici :

https://minecraft.fr/forum/threads/développer-un-plugin-sur-spigot-1-10-les-bases.189682/
https://minecraft.fr/forum/threads/développer-un-plugin-sur-spigot-1-10-les-commandes.190151/


~~~~ Commandes avec 1 seul argument ~~~~


Dans cette première partie, nous allons créer la commande /send qui nous enverra le mot que l'on a écrit en argument. Dans un premier temps, allez dans la classe principale de votre plugin et ajoutez cette ligne dans la méthode onEnable() :

Code:
getCommand("send").setExecutor(new SendCmd());


Explication : Cette ligne de code permet d'indiquer au démarrage du plugin de « créer » une nouvelle commande /send. Ici, la code de la commande se trouve dans la classe SendCmd() mais libre à vous de la mettre dans votre classe principale. Pour cela, il suffit de remplacer "new SendCmd()" par le mot "this".

Ensuite, créez la classe SendCmd() en pointant votre souris sur "new SendCmd()" puis cliquez sur "Create class 'SendCmd' ". Une fois la classe crée, vous devez obtenir un truc de ce style :

Code:
package fr.cercus.tutorial;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;

public class SendCmd implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender arg0, Command arg1, String arg2, String[] arg3) {
       return false;

    }
}


Explication des arguments de la méthode onCommand() :

→ CommandSender arg0 : Correspond à celui qui envoie cette commande (la console ou un joueur)
→ Command arg1 : la commande à exécuter
→ String arg2 : le label de la commande (= le nom de la commande)
→ String[] arg3 : Les argument de la commandes (C'est un tableau de string)

Pour des raisons de facilité de compréhension, je vous conseille de renommer arg0 par sender, arg1 par cmd, arg2 par label et arg3 par args.

On va maintenant vérifier que le nom de la commande est bien « send » : Ajouter la ligne suivante dans la méthode onCommand()

Code:
if(label.equalsIgnoreCase("send")) {
    // La suite du code
}


Explication : la méthode equalsIgnoreCase("send") permet de vérifier si le nom de la commande correspond à « send », en ignorant les majuscules.

On va maintenant vérifier que celui qui envoie la commande est un joueur puis que le nombre d'argument est de 1 (On oublie pas d'importer la classe Player de Spigot):

Code:
if(sender instanceof Player) {

    // On cast le sender en joueur car on sait que c'est un joueur
    Player p = (Player) sender;
    if(args.length == 1) { // Si le nombre d'arg est égale à 1 : /send <mot>
       //La suite du code 
    } else {
       // On envoie un message au joueur
       p.sendMessage("§cVous avez mis trop ou pas assez d'arguments");
       return true;

    }
}


Une fois les conditions faite, on va envoyer au joueur le mot que l'on a mis en argument :

Code:
p.sendMessage(args[0]);
return true;

Explication : args[0] correspond au premier argument : en effet, dans Java les tableaux commencent par l'indice 0 et non 1. Au final, vous devriez avoir un code de ce style :

Code:
package fr.cercus.tutorial;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class SendCmd implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
       if(label.equalsIgnoreCase("send")) {
           if(sender instanceof Player) {
               // On cast le sender en joueur car on sait que c'est un joueur
               Player p = (Player) sender;
               if(args.length == 1) { // Si le nombre d'arg est égale à 1 : /send <mot>
                  p.sendMessage(args[0]);
                   return true;
               } else {
                   // On envoie un message au joueur
                  p.sendMessage("§cVous avez mis trop d'arguments");
                   return true;
               }
           } else {
               return true;
           }
       }
       return false;
    }
}


On a presque fini, il reste a remplir le plugin.yml : En effet, sinon la commande ne s'exécute pas. Mettez donc ceci dans votre plugin.yml :

Code:
commands:
  send:
    description: Envoyer un seul mot


Compilez votre plugin, mettez le sur votre serveur et redémarrer/ reload votre serveur. Quand vous vous tapez « /send Bonjour » dans le chat, vous devez normalement recevoir le message « Bonjour »


~~~~ Commandes avec plusieurs arguments ~~~~


Maintenant, on va compliquer un peu : on va créer une commande /message qui reçoit comme argument un joueur et un mot. Cette commande aura la permission commande.message .

Comme pour l'exemple précédent, ajoutez cette ligne dans le onEnable() :

Code:
getCommand("message").setExecutor(new MessageCmd());


Comme pour le premier exemple, on va faire plusieurs vérifications : Vérifier que c'est un joueur qui exécute la commande, que ce joueur a la permission « commande.message », que le nombre d'argument est bien 2. Dans le cas contraire, on affiche un message au joueur avec la méthode sendMessage(String text) :

Code:
@Override

public boolean onCommand(CommandSender sender, Command cmd, String label, String[args) {
    if(cmd.getName().equalsIgnoreCase("message")) {
       if(sender instanceof Player) {
           // On cast le sender en joueur
           Player p = (Player) sender;
          if(p.hasPermission("commande.message")) {
               //On vérifie que le nombre d'argument est bien 2
               if(args.length == 2) {
                   // La suite du code
               } else {
                  p.sendMessage("§cVous avez mis trop ou pas assez d'arguments");
                   return true;
               }
           } else {
               p.sendMessage("§cVous n'avez pas la permission d'exécuter cette commande");
               return true;
           }
       }
    }
    return false;
}


Explication : On a ici une succession de conditions if. La méthode hasPermission(String perm) retourne true si le joueur a la permission perm (ici la permission est commande.message). Le reste du code est le même que dans le premier exemple.

Une fois ceci fait, on va récupérer le joueur que l'on a mis en argument. Pour cela, on va créer une variable target de type Player qui utilise la méthode getPlayer(String name) de Bukkit. Cette méthode permet d'obtenir le joueur (et donc toutes les caractéristiques de ce joueur : barre de vie, barre de nourriture, pseudo...), a partir d'une chaîne de caractère. Ajoutez donc cette ligne dans la suite du code :

Code:
Player target = Bukkit.getPlayer(args[0]);


Comme cette méthode peut retourner un null (Si le joueur n'existe pas), on va crée une condition et vérifier si la variable target est null (Cela evite d'avoir une erreur dans la console) :

Code:
if(target != null) {
    // Suite du code             
} else {
    p.sendMessage("§cCe joueur n'existe pas");
    return true;
}


Explication : On envoie un message au joueur si le nom du joueur spécifié dans l'argument 1 n'existe pas.

Enfin, on va vérifier que le joueur est bien en ligne puis si c'est le cas, lui envoyer le message :

Code:
if(target.isOnline()) {
    // args[1] contient le mot que l'on souhaite envoyer au joueur
    target.sendMesssage(args[1]);
    return true;                       
} else {
    p.sendMessage("§cCe joueur n'est pas en ligne");
    return true;
}


Explication : La méthode isOnline() vérifie si un joueur est en ligne ou non (true si en ligne et false si non en ligne)

Au final, on obtient ceci :

Code:
package fr.cercus.tutorial;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class MessageCmd implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
       if(cmd.getName().equalsIgnoreCase("message")) {
           if(sender instanceof Player) {
               // On cast le sender en joueur
               Player p = (Player) sender;
              if(p.hasPermission("commande.message")) {
                   //On vérifie que le nombre d'argument est bien 2 : /message <player> <mot>
                  if(args.length == 2) {
                      Player target = Bukkit.getPlayer(args[0]);
                      if(target != null) {
                           if(target.isOnline()) {
                               target.sendMessage(args[1]);
                           } else {
                               p.sendMessage("§cCe joueur n'est pas en ligne");
                               return true;
                           }
                      } else {
                           p.sendMessage("§cCe joueur n'existe pas");
                           return true;
                      }               
                   } else {
                      p.sendMessage("§cVous avez mis trop ou pas assez d'arguments");
                      return true;
                   }

               } else {
                  p.sendMessage("§cVous n'avez pas la permission d'exécuter cette commande");
                   return true;
               }
           }
       }
       return false;
    }
}


Ne pas oublier d'ajouter dans le plugin.yml cette commande :

Code:
message:
  description: Envoyer un mot a un joueur
  permission: commande.message


Au final, votre plugin.yml ressemble à ça :

Code:
name: Tutorial
Main: fr.cercus.tutorial.Main
author: cercus
version: 1.0
commands:
  send:
    description: Envoyer un seul mot au joueur
  message:
    description: Envoyer un seul mot a un joueur
    permission: commande.message


~~~~ Exercices d'application ~~~~


Maintenant, c'est un peu à votre tour de travailler (il ne suffit pas de lire le tutoriel mais de pratiquer, beaucoup pratiquer). Pour cela, je vous donne quelques exercices sur les commandes (Je ne vous donne pas une correction pour que vous puissiez chercher un peu (recopier un code ne sert à rien)). Ces exercices sont loin d'être exhaustif : Vous savez maintenant crée n'importe quel commande (issus de votre imagination par exemple).

Exercice 1 :

Créer une commande /broadcast <message> qui envoie un long message à tout les joueurs. Cette commande aura la permission commande.broadcast
Exemple : /broadcast &eCeci est un test &apour voir si ça marche

- Pour envoyer un message à tout le monde, on utilise la méthode Bukkit#broadcastMessage(String string).
- Pour remplacer les & suivi d'une lettre ou d'un chiffre (0-9, A-F, a-f, K-O, k-o, R or r. ) en couleur, la méthode ChatColor#translateAlternateColorCodes(char, message) peut être utilisé.


Exercice 2 :

Créer une commande /hasard <message> qui envoie à un joueur aléatoire du serveur un message. C'est une variante de l'exercice 1.

- On peut créer une liste contenant tout les joueurs qui sont en ligne sur le serveur puis choisir aléatoirement un joueur dans cette liste en utilisant la classe Random.


Exercice 3 :

Créer une commande /teleport <player> qui permet de se téléporter vers le joueur cible. Seul les OP peuvent exécuter cette commande.

- Pour téléporter un joueur à un endroit, la méthode teleport(Location location) peut être utilisé.

Exercice 4 :

Créer une commande /donxp qui prend comme argument un joueur connecté et un nombre de level qu'on veut donner au joueur. Exemple : "/donxp cercus 10" doit donner 10 levels d'xp à cercus. Il faudra vérifier que l'argument 2 (le nombre de level) soit un nombre...

- Pour vérifier qu'un string est un nombre, on peut utiliser la méthode Integer#parseInt(String string). Exemple d'utilisation :

Code:
 String nb = "10";
try{
     Integer.parseInt(nb);
catch(NumberFormatException e) {
     System.out.println("Ce n'est pas un nombre !");
}

~~~~ Quelques liens utiles ~~~~

Wiki de spigot : https://www.spigotmc.org/wiki/spigot/
Javadoc de spigot : https://hub.spigotmc.org/javadocs/spigot/overview-summary.html