NBTTagCompound avec WorldSavedData qui ne marche qu'à moitié



  • Salut tout le monde
    Sa faisait longtemps que je n'avais pas eu à demander de l'aide sur le fofo mais cela est révolu puisque aujourd'hui-même j'ai essayé le tuto de Blackout sur la persistance des données. Mais rien à faire ça ne veut pas fonctionner. Je m'explique :
    J'ai ajouté une nouvelle commande, le but est de taper un nom qu'il faut taper, ensuite je suis censé récupérer ce nom et l'enregistrer dans une ArrayList de String qui elle même est censée s'enregistrer dans mon WorldSavedData. Le prob, je me suis amusé avec les logs et j'ai testé tout cela, je peux enregistrer autant de noms qui me passe par la tête la liste marche et tout, quand je déco reco elle n'est pas init. Cependant quand je change de mon la liste est toujours la même et de + si je ferme le jeu et que je le relance, que je retourne sur la même map que précédemment ma liste sera réinit. Je ne comprends pas vraiment en gros ^^'
    Voici mes codes :

    Mon CommandsHandler

    
    package fr.mrplaigon.afewfun.common.handler;
    
    import java.util.List;
    
    import net.minecraft.command.CommandBase;
    import net.minecraft.command.CommandException;
    import net.minecraft.command.ICommandSender;
    import net.minecraft.command.WrongUsageException;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.util.ChatComponentTranslation;
    import net.minecraft.util.EnumChatFormatting;
    
    public class CommandsHandler extends CommandBase
    {
    
    @Override
    public String getCommandName()
    {
    return "afewfun";
    }
    
    @Override
    public String getCommandUsage(ICommandSender sender)
    {
    return "commands.afewfun.usage";
    }
    
    @Override
    public void processCommand(ICommandSender sender, String[] arguments)
    {
    if(arguments.length <= 0)
    {
    throw new WrongUsageException(this.getCommandUsage(sender));
    }
    if(arguments[0].matches("save") && arguments.length == 2)
    {
    ZoneListSaved.getActualZonesList().add(arguments[1]);
    ZoneListSaved.load();
    System.out.println(ZoneListSaved.getActualZonesList().isEmpty() ? ZoneListSaved.getActualZonesList().isEmpty() : ZoneListSaved.getActualZonesList().size());
    }
    }
    }
    
    

    Mon ZoneListSaved

    
    package fr.mrplaigon.afewfun.common.handler;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.world.WorldSavedData;
    import net.minecraft.world.storage.MapStorage;
    import net.minecraftforge.common.DimensionManager;
    import fr.mrplaigon.afewfun.common.core.AFewFunMod;
    
    public class ZoneListSaved extends WorldSavedData
    {
    
    private static ArrayList <string>actualZonesList = new ArrayList<string>();
    private static final String DATA_STORAGE_KEY = AFewFunMod.MODID + "actualZoneList";
    public ZoneListSaved(String key)
    {
    super(key);
    }
    
    @Override
    public void readFromNBT(NBTTagCompound compound) 
    {
    if(!actualZonesList.isEmpty())
    {
    Iterator <string>iterator = actualZonesList.iterator();
    while(iterator.hasNext())
    {
    compound.setString("actualZonesList", iterator.next());
    }
    }
    }
    
    @Override
    public void writeToNBT(NBTTagCompound compound) 
    {
    int size = compound.getInteger("actualZonesList");
    if(size < 0)
    for(int i = 0; i < size; i++)
    {
    String string = this.actualZonesList.get(i);
    this.actualZonesList.add(i, string);
    }
    }
    public static ZoneListSaved load()
    {
    if(DimensionManager.getWorlds().length < 1) 
    return null;
    MapStorage storage = DimensionManager.getWorlds()[0].mapStorage;
    final String KEY = getDataStorageKey(); // Si vous avez choisis de faire une fonction static String. Quoiqu'il en soit, la variable KEY que nous utiliserons ici représente votre clé. Si vous utilisez un attribut static, utilisez le directement.
    ZoneListSaved result = (ZoneListSaved)storage.loadData(ZoneListSaved.class, KEY);//On charge nos données
    if (result == null) //Si nos données n'existe pas, …
    { 
    result = new ZoneListSaved(KEY);// Alors on les crée ...
    storage.setData(KEY, result);// Et on les ajoutes à la mapStorage.
    }
    
    return result; //On retourne notre objet qui représente les données a sauvegarder
    }
    
    public static ArrayList <string>getActualZonesList() 
    {
    return actualZonesList;
    }
    
    public static String getDataStorageKey() 
    {
    return DATA_STORAGE_KEY;
    }
    }
    
    

    Merci d'avance =D</string></string></string></string>



  • Tu confond readFromNBT et writeToNBT.
    readFromNBT = lire depuis le NBT, donc tu as un NBT remplis et tu dois charger ta liste.
    writeToNBT = ecrire vers le NBT, donc tu as un NBT vide que tu dois remplir

    Pour l'instant tu fais l'inverse, c'est pour ça que ça ne marche pas.

    actualZonesList ne doit pas être en static, soit tu appel Load dès que tu veux l'instance de ZoneListSaved, soit s'il n'y a qu'une seule instance, tu fais un singleton.



  • Je ne comprends pas très bien 
    Comment je peux faire une instance de ZoneListSaved si il n'est pas static ?
    Il faut que je fasse une instance de ZoneListSaved comme dans la classe principale ? Dans ce cas autant passer la méthode load en un type void…

    Au fait je viens de rectifier le soucis dans les 2 méthodes NBTTag



  • Up
    Je n'ai toujours rien trouvé de +
    Blackout à l'aide xD



  • @Override
    public void readFromNBT(NBTTagCompound compound)
    {
    if(!actualZonesList.isEmpty())
    {
    Iterator <string>iterator = actualZonesList.iterator();
    while(iterator.hasNext())
    {
    compound.setString("actualZonesList", iterator.next());
    }
    }
    }
    

    pourquoi tu setString dans un Read?

    on set le tag dans le Write et on get dans le read pas l inverse xD
    (j'ai fait la même erreur pas plus tard que ce matin)
    sinon forcement ça fonctionne pas</string>



  • Blackout me l'avait déjà signalé plus haut ^^
    J'ai modifié mais en vain rien à faire, le problème persiste …



  • ici de set un String: compound.setString("actualZonesList", iterator.next());

    ici tu recupere un int /int size = compound.getInteger("actualZonesList");

    ça peut pas fonctionné si tu set un string tu récupère un string
    si tu veut pour les int ca marche pareil



  • @'VirusZ':

    ici de set un String: compound.setString("actualZonesList", iterator.next());

    ici tu recupere un int /int size = compound.getInteger("actualZonesList");

    ça peut pas fonctionné si tu set un string tu récupère un string
    si tu veut pour les int ca marche pareil

    Si ça fonctionne, j'ai mis le même code dans mon entity.
    Le seul truc qui doit être en commun c'est pas le type de getter / setter c'est le String passé en argument. Là en l'occurence "actualZoneList".

    Tkt les NBT je sais comment ça marche, maintenant. Même si il est vrai qu'il y a plusieurs mois, je n'y comprenais rien xD



  • Tu as combien d'instance de ZoneListSaved dans ton mod ? une instance unique ou plusieurs instance ?



  • @'Blackout':

    Tu as combien d'instance de ZoneListSaved dans ton mod ? une instance unique ou plusieurs instance ?

    Je n'ai aucune instance de ZoneListSaved dans mon mod, puique je ne procède que par des méthodes statics : mon getter d'ArrayList <string>en static et la méthode load aussi en static</string>


  • Administrateurs

    Il faut éviter de mélanger les méthodes non static avec des variables static.
    Fait toi une instance unique et static de la classe ZoneListSaved, passe la variable actualZonesList en non static puis sert toi de l'instance de la classe ZoneListSaved pour get la liste.



  • Je vais réfléchir à ce que tu m'as dit 🙂



  • Renseignes toi sur le design pattern Singleton 😉