Résolu Problème avec les HashMap

Bizu

Bucheron
21 Juillet 2020
22
0
13
24
Ah désoler je pensais que tu avais déjà compris x) c'est InventoryClickEvent
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
157
455
247
21
Mìlhüsa
Java:
HumanEntity human = e.getWhoClicked();
if(human instanceof Player) {
    Player player = (Player) human;
    ...
}
else {
    // humain, mais pas un joueur ;
    // généralement un NPC créé par un autre plugin
}

J'aimerais aussi que tu m'envoies le code de ta méthode complète qui gère l'évènement afin que je puisse commenter un peu ce que tu as fait, notamment pour corriger tes NPEs :^)
 

Bizu

Bucheron
21 Juillet 2020
22
0
13
24
Java:
   @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        if (!(event.getWhoClicked() instanceof Player)) return;
        Player p = (Player) event.getWhoClicked();

        if (!ScrollerInventory.users.containsKey(p.getUniqueId())) return;
        ScrollerInventory inv = ScrollerInventory.users.get(p.getUniqueId());
        if (event.getCurrentItem() == null) return;
        if (event.getCurrentItem().getItemMeta() == null) return;
        if (event.getCurrentItem().getItemMeta().getDisplayName() == null) return;


        if (event.getClickedInventory().getName().equalsIgnoreCase(ChatColor.RED + "Reports")) {

            if (event.getCurrentItem().getItemMeta().hasDisplayName() && event.getClick().isLeftClick()) {
                event.getWhoClicked().sendMessage("§a Téléportation au joueur fautif");

                    String playerName = Report.hash.get(event.getCurrentItem().getItemMeta().getDisplayName());
                    Player playerId = Bukkit.getPlayer(playerName);
                    event.getWhoClicked().teleport(playerId);
                    event.getWhoClicked().closeInventory();

                for (String key : Report.content.keySet()) {
                    Player player6 = Bukkit.getPlayer(key);
                    player6.sendMessage(ChatColor.GREEN + "Un modérateur traite ton report");
                    System.out.print(player6.getName());
                    player6.playSound(player6.getLocation(),Sound.NOTE_BASS,5,5);
                }

            }



            else if(event.getCurrentItem().getItemMeta().hasDisplayName() && event.getClick().isRightClick()){

                event.getCurrentItem().setType(Material.AIR);
                event.getClickedInventory().remove(event.getCurrentItem());
                Report.items.clear();
            }
            }
Voici donc, et au passage je pense que tu as mal compris : Je veux stocker un joueur DANS une commande puis réutiliser ce dit joueur pour faire des choses dans un Event
aussi je sais que String key : Report.hash.keySet c'est n'importe quoi j'avais essayé avant de me rendre compte de ma bêtise faut que je remplace mais je ne sais pas par quoi :/
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
157
455
247
21
Mìlhüsa
Java:
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
   HumanEntity human = e.getWhoClicked();
   if(!(human instanceof Player))
      return;
   
   Player moderator = (Player) human;
   
   ItemStack clickedItem = e.getCurrentItem();
   if(clickedItem == null)
      return;
   
   ItemMeta clickedMeta = clickedItem.getItemMeta();
   if(clickedMeta == null || !clickedMeta.hasDisplayName()) // getDisplayName() ne renvoit jamais `null`, mais une chaîne vide `""`
      return;
   
   if(!ScrollerInventory.users.containsKey(moderator.getUniqueId()))
      return;
   
   if(!e.getView().getTitle().equals /* la casse ne peut pas être autre chose que ce que tu as mis */(ChatColor.RED + "Reports"))
      return;
   
   String playerName = ChatColor.stripColor(clickedMeta.getDisplayName()); // pourquoi passer par ta Map?
   Player reportedPlayer = Bukkit.getPlayer(playerName);
   if(reportedPlayer == null) {
      moderator.sendMessage(ChatColor.RED + "Le joueur est déconnecté");
      return;
   }
   
   ClickType click = e.getClick();
   if(click.isLeftClick()) {
      moderator.closeInventory();
      
      if(!moderator.teleport(reportedPlayer)) {
         moderator.sendMessage(ChatColor.DARK_RED + "Téléportation refusée par un autre plugin");
         return;
      }
      else {
         moderator.sendMessage(ChatColor.GREEN + "Vous venez d'être téléporté au joueur signalé");
      }
      
      // Je ne connais pas ta classe `Report`, impossible pour moi de savoir comment afficher
      // au joueur signaleur que son signalement est en train d'être traité
   }
   else if(click.isRightClick()) {
      // Je ne connais pas ta classe `ScrollerInventory`, impossible pour moi de savoir comment
      // y enlever un item proprement
     
//    Report.items.clear();
      // clear() enlève TOUS les items ; or tu veux enlever uniquement l'item sélectionné.
      // sans ta classe `Report`, je ne sais pas quel est le type de ta variable `Report.items`
   }
}

Comme je te l'avais dit ici, il faut que tu crées une classe pour gérer un seul signalement. Ce que tu veux faire est trop complexe pour que tu puisses te permettre de t'en passer.

Voici donc, et au passage je pense que tu as mal compris : Je veux stocker un joueur DANS une commande puis réutiliser ce dit joueur pour faire des choses dans un Event
aussi je sais que String key : Report.hash.keySet c'est n'importe quoi j'avais essayé avant de me rendre compte de ma bêtise faut que je remplace mais je ne sais pas par quoi :/
Tu ne peux pas stocker de données dans une commande ; il faut que ta commande enregistre les données qu'elle a collectées dans une variable, typiquement une List<Report>, avec Report une classe qui représente un seul signalement. Comme je te l'ai déjà dit, ta commande Report est très mal nommée et devrait s'appeler CommandReport.
 
  • J'aime
Reactions: Niz

Bizu

Bucheron
21 Juillet 2020
22
0
13
24
On se comprend mal x) " il faut que tu crées une classe pour gérer un seul signalement. " comment ça ? Je veux dire, une class ne peux pas avoir de paramètres ???
Oui je sais que je ne peux pas stocker de données dans une commande je parlais de stocker dans une HashMap, et aussi ma commande Report s'appelle report pour des raisons de simplicités ( les joueurs ne vont pas savoir qu'il faut taper CommandReport )
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
157
455
247
21
Mìlhüsa
Je veux dire, une class ne peux pas avoir de paramètres ???
Et si, c'est une fonction spéciale qui s'appelle un constructeur en programmation, et qui en Java se déclare comme toute autre fonction, sauf qu'elle n'a pas de type de retour et qu'elle a pour nom le nom de la classe.
Java:
public class Report {
   private static final List<Report> REPORTS = new LinkedList<>();
   private final UUID author;
   private final UUID subject;
   private final String reason;
   private final long date;
   
   private Report(UUID author, UUID subject, String reason, long date) {
      if(author == null) throw new NullPointerException("`author` must not be null");
      if(subject == null) throw new NullPointerException("`subject` must not be null");
      if(reason == null || reason.isEmpty()) throw new IllegalArgumentException("`reason` must not be empty");
      if(date <= 0) throw new IllegalArgumentException("`date` must be strictly greater than zero");
      
      this.author = author;
      this.subject = subject;
      this.reason = reason;
      this.date = date;
      
      REPORTS.add(this);
   }
   
   public Report(UUID author, UUID subject, String reason) {
      // appelle le premier constructeur, avec `date` = l'heure actuelle
      this(author, subject, reason, System.currentTimeMillis());
   }
   
   /**
    * @return La liste de tous les signalements, en lecture seule.
    */
   public static List<Report> getReports() {
      return Collections.unmodifiableList(REPORTS);
   }
   
   /**
    * @return La liste de tous les signalements effectués par le joueur spécifié.
    */
   public static List<Report> getReportsBy(UUID author) {
      List<Report> reports = new LinkedList<>();
      for(Report report : REPORTS) {
         if(report.author.equals(author)) {
            reports.add(report);
         }
      }
      
      return reports;
   }
   
   /**
    * @return La liste de tous les signalements du joueur spécifié.
    */
   public static List<Report> getReportsFor(UUID subject) {
      List<Report> reports = new LinkedList<>();
      for(Report report : REPORTS) {
         if(report.subject.equals(subject)) {
            reports.add(report);
         }
      }
      
      return reports;
   }
   
   /**
    * @return L'UUID de l'auteur du signalement.
    */
   public UUID getAuthor() {
      return author;
   }
   
   /**
    * @return L'UUID du joueur signalé.
    */
   public UUID getSubject() {
      return subject;
   }
   
   /**
    * @return La raison du signalement.
    */
   public String getReason() {
      return reason;
   }
   
   /**
    * @return La date (en millisecondes) du signalement.
    */
   public long getDate() {
      return date;
   }
}

Puis après il te suffit d'appeler le constructeur en utilisant l'opérateur new :
Java:
UUID author = ...;
UUID subject = ...;
String reason = ...;
Report report = new Report(author, subject, reason);

L'avantage est que tu peux créer des fonctions utilitaires pour éviter de réécrire plusieurs fois le même morceau de code, style :
Java:
UUID subject = ...;
List<Report> reports = Report.getReportsFor(subject);
Qui renvoit la liste des signalements dont subject est le sujet — c.-à-d. le joueur signalé.

Tu peux aussi rajouter tes propres variables, comme par ex. un booléen wasProcessed qui est sur true si et seulement si le signalement a été traité, et rajouter tes propres fonctions :
Java:
public OfflinePlayer getAuthorPlayer() {
   return Bukkit.getOfflinePlayer(author);
}

public OfflinePlayer getSubjectPlayer() {
   return Bukkit.getOfflinePlayer(subject);
}

public ItemStack createRenderItem() {
   ItemStack item = new ItemStack(Material.PAPER);
   // ...
   
   return item;
}

public static List<ItemStack> createRenderItems(boolean filterProcessedOut) {
   List<ItemStack> items = new ArrayList<>(REPORTS.size());
   for(Report report : REPORTS) {
      if(!filterProcessedOut || !report.wasProcessed) {
         items.add(report.createRenderItem());
      }
   }
   
   return items;
}
Java:
Report report = ...;
ItemStack stack = report.createRenderItem();

ma commande Report s'appelle report pour des raisons de simplicités ( les joueurs ne vont pas savoir qu'il faut taper CommandReport )
Le nom de la commande est écrit dans plugin.yml ; le nom de la classe ne change strictement rien. De plus, tu as la même classe Report pour deux commandes — /report et /reports. Tu pourrais renommer ta classe Affaefaefcaflpaef, tes deux commandes seront toujours /report et /reports.
 
  • J'aime
Reactions: Niz

Bizu

Bucheron
21 Juillet 2020
22
0
13
24
Bonjour ! Alors tout d'abord merci de ces informations, je vais essayer d'en apprendre plus sur les constructeurs, et en second lieu j'ai plusieurs questions :

Comment je peux attribuer aux 4 variables (
private final UUID author;
private final UUID subject;
private final String reason;
private final long date;
)
leurs attributs respectifs ? Je veux dire, ça ne va pas attribuer l'uuid author tout seul ... ?

et pourquoi elles ne sont pas initalisés ?

Et je ne comprend pas comment private static final List<Reports> REPORTS = new LinkedList<>(); peux fonctionner étant donné que en paramètre de la List il y a Reports ... ? Je veux dire, on peux mettre des ItemStack des Player ou d'autres choses du genre mais Reports est égal à LA class ?
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
157
455
247
21
Mìlhüsa
Comment je peux attribuer aux 4 variables [...] leurs attributs respectifs ? Je veux dire, ça ne va pas attribuer l'uuid author tout seul ... ?
Avec l'opérateur new, qui appelle le constructeur :
Java:
public class Report {
    private static final List<Report> REPORTS = new LinkedList<>();
    private final UUID author;
    private final UUID subject;
    private final String reason;
    private final long date;
    
    // constructeur
    private Report(UUID author, UUID subject, String reason, long date) {
        if(author == null) throw new NullPointerException("`author` must not be null");
        if(subject == null) throw new NullPointerException("`subject` must not be null");
        if(reason == null || reason.isEmpty()) throw new IllegalArgumentException("`reason` must not be empty");
        if(date <= 0) throw new IllegalArgumentException("`date` must be strictly greater than zero");
        
        this.author = author;
        this.subject = subject;
        this.reason = reason;
        this.date = date;
        
        REPORTS.add(this);
    }
}

// new appelle le constructeur Report.Report(UUID, UUID, String, long)
Report report = new Report(author, subject, reason, date);

https://www.jmdoudoux.fr/java/dej/chap-poo.htm
Section 4.5.6 « Les constructeurs ».

Et je ne comprend pas comment private static final List<Reports> REPORTS = new LinkedList<>(); peux fonctionner étant donné que en paramètre de la List il y a Reports ... ? Je veux dire, on peux mettre des ItemStack des Player ou d'autres choses du genre mais Reports est égal à LA class ?
Pourquoi ne pourrait-on pas ? Tu peux bien avoir un cercle dans un cercle.
 

Bizu

Bucheron
21 Juillet 2020
22
0
13
24
D'accord d'accord, merci bien pour toutes ces précieuses informations, je te souhaite une bonne journée car mon problème est résolu et je te remercie mille fois pour ton aide ^^

Et j'espère un jour atteindre tes connaissances :)