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

Achoc

Mineur des cavernes
21 Avril 2020
61
0
31
24
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.
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
157
455
247
21
Mìlhüsa
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
 

Achoc

Mineur des cavernes
21 Avril 2020
61
0
31
24
Il y a quelques erreurs ça doit venir du fait que je suis en 1.8.9.
1622630383459.png
 

Detobel36

Créateur de plugins (PhoenixRebirth)
Support
17 Août 2012
10 530
24
2 247
347
27
Bruxelles - Belgique
www.phoenix-rebirth.fr
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
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
157
455
247
21
Mìlhüsa
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é.
 

Achoc

Mineur des cavernes
21 Avril 2020
61
0
31
24
J'ai modifié recopier créer une nouvelle class exprès et j'ai toujours des erreurs
1622654885296.png
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
157
455
247
21
Mìlhüsa
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

Achoc

Mineur des cavernes
21 Avril 2020
61
0
31
24
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 ?
 

Achoc

Mineur des cavernes
21 Avril 2020
61
0
31
24
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.