Plugin Résolu [Mon plugin] Problème de condition d' "égalité" d'argument et d'autres problèmes

iKreal

Massacreur de Mouton
30 Octobre 2015
40
2
23
22
Bonjour ! :)
Je développe actuellement en Java (sur Eclipse) avec Spigot pour commencer à créer des plugins Minecraft.
Le problème est sans doute très facilement résoluble mais je bloque depuis plus d'une heure et j'ai d'autres questions à côté.
Je souhaite créer une nouvelle commande avec plusieurs arguments, commande qui enregistre des messages, des mots, pour pouvoir les écrire plus rapidement.
Voici la syntaxe de ma commande : /message save,load,delete <numéro> <message>
1) En fait, je souhaite que le joueur puisse enregistrer 5 messages dans un fichier yml mais je me demande si ce ne serait pas possible à les écrire dans un fichier txt ?
2) De plus, il faudrait un fichier dans lequel il pourrait avoir des sections qui s'ajoutent avec les pseudos des joueurs, ex :
Code:
messages:
  pseudo1:
   1:
   2:
   3:
   4:
   5:
  pseudo2:
   1:
   2:
   3:
   4:
   5:
Et je ne sais pas comment écrire dans ces fichiers à partir de Java... J'ai également entendu parler de "skript", ce qui m'a perdu dans cette broussaille.

3) Ensuite, je me suis dit qu'avant de sauvegarder les messages, je pourrais déjà essayer d'en charger. Le joueur pourrait alors utiliser la commande : /message load <numéro>.
Voici dans la classe principale les quelques lignes de codes concernant tout cela :
Code:
package fr.ikreal.monplugin;

import org.bukkit.plugin.java.JavaPlugin;
import fr.ikreal.monplugin.commands.CommandTest;

public class MonPlugin extends JavaPlugin {
   
   @Override
   public void onEnable() {
       saveDefaultConfig();
       System.out.println("Le plugin vient de démarrer.");
       getCommand("message").setExecutor(new CommandTest(this));
       getServer().getPluginManager().registerEvents(new MonPluginListeners(), this);
   }

   @Override
   public void onDisable() {
       System.out.println("Le plugin vient de s'éteindre.");
   }
   
}
Et voici le code dans la classe de ma commande :
Code:
package fr.ikreal.monplugin.commands;

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

import fr.ikreal.monplugin.MonPlugin;

public class CommandTest implements CommandExecutor {

   private MonPlugin main;

   public CommandTest(MonPlugin monPlugin) {
       this.main = monPlugin;
   }

   @Override
   public boolean onCommand(CommandSender sender, Command cmd, String msg, String[] args) {

       if(sender instanceof Player) {
           Player player = (Player)sender;

           if(cmd.getName().equalsIgnoreCase("message")) {

               //message ==> pas assez d'arguments
               if(args.length <2) {
                   player.sendMessage("§4Erreur de syntaxe : §e/message §asave,load,delete §b<numéro> §c(<message>)");
               }

               //message <text>
               if(args.length >=2) {
                   if(args.length == 2 && args[0] == "load") {
                       System.out.println("Load trouvé");
                       player.sendMessage(main.getConfig().getString("messages." + args[1]).replaceAll("&", "§"));
                                               return true;
                   }
                                       if(args.length ==3 && args[0] == "save") {
                                               //Code pour enregistrer des messages dans le fichier config.yml
                                       }
               }

           }
       }

       return false;

   }
}
(oui je l'ai appelé CommandTest...)
Le problème ici, c'est que lorsque je lance dans le jeu la commande /message load 1, rien ne se passe, comme si la condition (args[0] == "load") n'était pas vérifiée... J'ai testé en mettant une sortie de texte dans la console (on peut le voir sur le code ci-dessus) mais aucun message n'apparaît.

Donc, en résumé, voici les différents problèmes et questions :
a) Vaut-il mieux enregistrer du texte dans un txt (si on le peut) ou yml ?
b) Comment écrire dans ces fichiers avec du code Java ?
c) Comment créer de nouvelles sections avec les noms des joueurs automatiquement ?
d) Quel est le problème qui fait que la commande ne fonctionne pas ?

Si vous avez besoin du message d'erreur, je peux vous l'envoyer, pas de souci ! :)
Voilà, c'est tout (c'est déjà beaucoup !)
Merci à ceux qui ont pris le temps pour lire mes questions et merci à ceux qui éventuellement m'aideront. Si vous avez la réponse ne serait-ce qu'à une question, j'en serai fort reconnaissant.
Amicalement,
iKreal (alias Koelite).
 

Syrows

Développeur
7 Juillet 2016
137
20
130
23
Bien le bonjour. Tout d'abord, j'espère bien avoir compris ton problème et je vais essayer d'y répondre le plus précisément possible. Cependant, il n'est pas toujours facile de savoir si c'est exactement ce que tu souhaites, j'espère donc que cette réponse te conviendra.

Premièrement, résumons un peu pour savoir si tout est bien compris de mon côté. En gros, lors de l'exécution de la commande /message save <numéro> <message>, nous sauvegardons un message dans un fichier (yml ou txt, l'explication viendra ensuite). Lors de l'exécution de la commande /message load <numéro>, celui-ci devrait en toute logique s'afficher et si l'argument 0 correspond à delete, celui-ci doit se supprimer. Bien. J'ai maintenant toute la base pour répondre à tes questions.

Tout d'abord, répondons à la premièrement question: "Fichier .txt ou .yml ?". Personnellement, je privilégierai ici les fichiers avec l'extension .yml car leur forme sera très facile d'utilisation puisque Spigot propose un ensemble de méthodes et de classes pour écrire du texte, le modifier, le récupérer ou le supprimer très facilement. De plus, comme tu as l'air de débuter dans le langage de programmation qu'est Java, ce sera beaucoup plus facile pour toi.
Note: Si tu as des questions concernant l'utilisation des méthodes, constructeurs et classes, la documentation de Bukkit pourra t'éclairer.

Cependant, je me permets de parler de l'extension de fichier .json qui te sera peut-être utile par la suite. En effet, la gestion de tes messages va consommer par mal de ressources notamment avec les sauvegardes des modifications ainsi que les chargements que tu peux faire. C'est pour cela qu'il serait préférable de créer un objet stocké dans une HashMap et associé à un joueur pour faire les modifications directement dans ces données et non sauvegarder le fichier à chaque fois. Ainsi, avec une API utilisant json (comme Gson, Jackson, ou json-simple) tu pourras sauvegarder et charger ces données très facilement directement à la déconnexion et à la connexion du joueur et en seulement quelques lignes contrairement aux fichiers .yml qui en demanderont peut-être le double (Note: si tu veux utiliser cette technique, créer un fichier par joueur serait préférable et te permettrait de stocker plus de données).

Pour la deuxième question, "Comment écrire dans ces fichiers avec du code Java ?", Spigot met, comme je l'ai dis plus haut, un ensemble de classes et de méthodes pour faire ceci (avec les fichiers .yml). Je ne vais pas toutes te les donner car ça n'a aucun intérêt et il y en a beaucoup trop. Cependant, tu utiliseras surement la classe YamlConfiguration ou encore l'interface ConfigurationSection pour faire ce dont tu as besoin.

Pour charger un fichier rien du plus simple:
Code:
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);

Ensuite, tu auras accès à un ensemble de méthodes pour récupérer des String, Integer, Double, Float, ect. Google est ton ami pour en savoir un peu plus.

Passons à la question "Comment créer de nouvelles sections avec les noms des joueurs automatiquement ?". Rien de plus simple, tu crées une section à la création de ton fichier comme ceci:

Code:
//chargement de la config
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);

//création de la section
ConfigurationSection section = config.createSection(taSection);

//sauvegarde du fichier
config.save(file);

Ensuite, lors de la première connexion du joueur, tu récupères la section et tu en crées une nouvelle à l'intérieur avec l'UUID ou le nom du joueur.

Enfin, passons à la dernière question "Quel est le problème qui fait que la commande ne fonctionne pas ?". C'est très simple. Dans ta condition, tu fais ceci:
Code:
if(args[0] == "load")
Or, tu ne peux pas utiliser "==" pour vérifier une égalité entre deux String. Pour faire ceci, tu dois utiliser une méthode qui est equals(); ou equalsIgnoreCase();. Elles prennent toutes les deux un String en paramètre. Le code donne donc ceci:
Code:
if(args.length(); >= 2 && args[0].equals("load"){

Voilà, j'espère t'avoir aidé !
 

iKreal

Massacreur de Mouton
30 Octobre 2015
40
2
23
22
Bonjour Syrows, merci beaucoup pour ta réponse, c'est exactement ce que je souhaitais ! :)
Je vais essayer de faire ça, et je te tiens au courant, notamment si je bloque ou si j'ai d'autres problèmes (ce qui est très probable).
Merci encore !

Je viens de relire ton message, et là il y a un problème puisque tu me dis qu'une HashMap serait plus pratique qu'enregistrer à chaque fois, mais je ne sais pas du tout comment m'en servir. De plus, tu m'as montré comment créer une section, comment charger un fichier, mais pas comment écrire dans une section.. Et d'ailleurs, comment charge-t-on uniquement une valeur dans une section et non pas le fichier entier ? Lorsque le joueur choisit son message, il faut récupérer la valeur dans la section. Enfin, je suis encore confus dans tout cela :/
 
Dernière édition par un modérateur:

Syrows

Développeur
7 Juillet 2016
137
20
130
23
Si tu ne sais pas comment gérer des données avec un stockage dans une HashMap, il va falloir te renseigner. Pour résumer, une HashMap ou Map est une liste de données associant à chaque clé une valeur. Ici, ta clé sera donc l'UUID du joueur ou son pseudo par exemple et la valeur l'objet stockant les messages.

Pour écrire dans une section, rien de plus simple:
Code:
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);

ConfigurationSection section = config.getConfigurationSection(path);

//écrire dans la section
section.set(key, value);
"key" correspond à un String qui est en quelque sorte le chemin d'accès à ta valeur et value correspond à ce que tu veux lui associer. Exemple: message: "Mon message". Ici,key=message et value="Mon message".

Pour récupérer des données dans des sections, tu fais taSection.getString(path); par exemple. Tu peux récupérer des Integer avec getInt(path);, des Double avec getDouble(path); et ainsi de suite. "path" correspond au chemin d'accès de la valeur. Par exemple, si ma section principale se nomme "players", le joueur se nomme "test" et ma clé "message", le chemin d'accès à la valeur se trouvant à "message" est "players.test.message".
 

iKreal

Massacreur de Mouton
30 Octobre 2015
40
2
23
22
Ok merci pour ta réponse, je vais me renseigner sur les HashMaps et essayer tout ça ! :)