Comment sauvegarder l'inventaire d'un joueur dans une variable ?

Achoc

Mineur des cavernes
21 Avril 2020
61
0
31
25
Je créé un plugin et j'aimerai pouvoir sauvegarder l'inventaire du joueur avec une commande et plus tard pouvoir le récupéré avec une autre commande.
 
Bonsoir,

A priori il suffit juste de sauvegarder avec les différents accesseurs de PlayerInventory [#getStorageContents(), #getArmorContents(), #getExtraContents()] puis de recharger avec les mutateurs #set..., donc faire une classe qui s'occupe de faire ça plus ou moins implicitement.

Java:
public class InventoryBackup {
   private final UUID holder;
   private final ItemStack[] storageContents;
   private final ItemStack[] armorContent;
   private final ItemStack[] extraContents; // extraContents[0] == main secondaire (off hand)
   
   public InventoryBackup(Player player) {
      this(player.getInventory());
   }
   
   public InventoryBackup(PlayerInventory inventory) {
      this.holder = Objects.requireNonNull(inventory.getHolder(), "Cannot save a playerless inventory").getUniqueId();
      this.storageContents = inventory.getStorageContents();
      this.armorContent = inventory.getArmorContents();
      this.extraContents = inventory.getExtraContents();
      
//    pour sauvegarder le curseur:
//    inventory.getHeldItemSlot();
//    inventory.setHeldItemSlot(itemSlot);
   }
   
   public void restore() {
      Player holder = Bukkit.getPlayer(this.holder);
      Objects.requireNonNull(holder, "Cannot restore an offline player inventory");
      
      PlayerInventory inventory = holder.getInventory();
      inventory.setStorageContents(storageContents);
      inventory.setArmorContents(armorContent);
      inventory.setExtraContents(extraContents);
      holder.updateInventory();
   }
}
Je n'ai pas testé le code, mais j'ai vérifié les fonctions et normalement ça devrait marcher.

Cordialement,
ShE3py
 
Il y a quelques erreurs ça doit venir du fait que je suis en 1.8.9.
1622630383459.png
 
Salut,

Donc @ShE3py écrit:
Java:
   public InventoryBackup(Player player) {
      this(player.getInventory());
   }
Et toi tu écris:
Java:
   public void InventoryBackup(Player player) {
      this(player.getInventory());
   }

La différence est grande pour Java ;)


Cordialement,
Detobel36
 
Les deux fonctions InventoryBackup(...) sont des constructeurs, ils ont exactement le même nom que la classe et ne doivent pas avoir de type de return (même void).
Cela permet d'utiliser l'opérateur new avec tes propres paramètres et d'initialiser ta classe comme tu le veux :
Java:
PlayerInventory inventory = ...;
InventoryBackup backup = new InventoryBackup(inventory);

Le premier constructeur qui prend un joueur est juste un raccourcis (this(player.getInventory()) appelant le second constructeur)
Java:
Player player = ...;
InventoryBackup backup = new InventoryBackup(player);
InventoryBackup backup = new InventoryBackup(player.getInventory());

Après pour l'erreur sur le Objects.requireNonNull(...) : vérifie que tu as bien importé la classe de java.util.Objects et non d'un autre package.
Sinon tu peux simplement remplacer avec des if :
Java:
//  InventoryBackup(PlayerInventory inventory)
HumanEntity player = inventory.getHolder();
if(player == null)
   throw new IllegalArgumentException("Cannot save a playerless inventory");

this.holder = player.getUniqueId();
// etc.
Java:
// restore()
Player holder = Bukkit.getPlayer(this.holder);
if(holder == null)
   throw new IllegalStateException("Cannot restore an offline player inventory");

PlayerInventory inventory = holder.getInventory();
// etc.

Enfin, si tu joues en 1.8, remplace simplement les deux storageContents et extraContents par une seule variable contents et utilise le getter/setter approprié.
 
J'ai modifié recopier créer une nouvelle class exprès et j'ai toujours des erreurs
1622654885296.png
 
Après pour l'erreur sur le Objects.requireNonNull(...) : vérifie que tu as bien importé la classe de java.util.Objects et non d'un autre package.
Sinon tu peux simplement remplacer avec des if :
Java:
// InventoryBackup(PlayerInventory inventory)
HumanEntity player = inventory.getHolder();
if(player == null)
   throw new IllegalArgumentException("Cannot save a playerless inventory");

this.holder = player.getUniqueId();
// etc.
Java:
// restore()
Player holder = Bukkit.getPlayer(this.holder);
if(holder == null)
   throw new IllegalStateException("Cannot restore an offline player inventory");

PlayerInventory inventory = holder.getInventory();
// etc.
Enfin, si tu joues en 1.8, remplace simplement les deux storageContents et extraContents par une seule variable contents et utilise le getter/setter approprié.
Ça ne me dérange pas de te remettre le code pour la 1.8 (le miens étant pour la 1.16), mais bon faut aussi que tu comprennes les erreurs simples, au lieu d'attendre un code préfait qui fonctionne du premier coup. L'idée est plutôt de te donner la piste à explorer qu'une solution fonctionnelle.
Java:
public class InventoryBackup {
   private final UUID holder;
   private final ItemStack[] contents;
   private final ItemStack[] armorContent;
   
   public InventoryBackup(Player player) {
      this(player.getInventory());
   }
   
   public InventoryBackup(PlayerInventory inventory) {
      HumanEntity player = inventory.getHolder();
      if(player == null)
         throw new IllegalArgumentException("Cannot save a playerless inventory");
      
      this.holder = player.getUniqueId();
      this.contents = inventory.getContents();
      this.armorContent = inventory.getArmorContents(); // peut-être déjà inclus dans #getContents() pour la 1.8
      
//    pour sauvegarder le curseur:
//    inventory.getHeldItemSlot();
//    inventory.setHeldItemSlot(itemSlot);
   }
   
   public void restore() {
      Player holder = Bukkit.getPlayer(this.holder);
      if(holder == null)
         throw new IllegalStateException("Cannot restore an offline player inventory");
      
      PlayerInventory inventory = holder.getInventory();
      inventory.setContents(contents);
      inventory.setArmorContents(armorContent);
      holder.updateInventory();
   }
}
 
  • J'aime
Reactions: Detobel36
Je n'es plus d'erreur mais maintenant comment je peux récupérer dans une autre class les objets pour qu'ils s'exécute quand je tape une commande ?
 
Je viens de commencer à développer je comprends dans les grandes lignes comment marche le java et j'utilise le forum pour répondre aux questions sur les choses que je ne comprends pas par exemple ce qui me bloquais là c'étais que je ne connaissais pas le setContents.