MFF

    Minecraft Forge France
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes
    • Forge Events
      • Automatique
      • Foncé
      • Clair
    • S'inscrire
    • Se connecter

    Petit problème Syncro ExtProp HashSet

    Planifier Épinglé Verrouillé Déplacé Résolu 1.7.x
    1.7.10
    11 Messages 2 Publieurs 1.7k Vues 1 Watching
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • DeletedD Hors-ligne
      Deleted
      dernière édition par

      Bonjour, bonjour,
      Je poste ce sujet pour vous demander de l’aide à propos d’un drôle de problème d’ExtProp et de synchro. Alors c’est bizarre mais quand je print la taille de mon HashSet, côté client elle est toujours égale à 0, et côté serveur, toujours à 1. Bref voici le code :
      ExtProp :

      
      import java.util.ArrayList;
      import java.util.HashSet;
      import java.util.List;
      import java.util.Set;
      
      import net.minecraft.entity.Entity;
      import net.minecraft.entity.player.EntityPlayer;
      import net.minecraft.entity.player.EntityPlayerMP;
      import net.minecraft.nbt.NBTTagCompound;
      import net.minecraft.nbt.NBTTagList;
      import net.minecraft.nbt.NBTTagString;
      import net.minecraft.world.World;
      import net.minecraftforge.common.IExtendedEntityProperties;
      import net.minecraftforge.common.util.Constants;
      
      public class ExtendedEntityPropertiesPlayer implements IExtendedEntityProperties 
      {
      
      public final static String EXT_PROP_NAME = "ExtProp" + DICraftMod.MODID;
      private final EntityPlayer player;
      private boolean healthRegenState;
      private boolean strengthState;
      private boolean agilityState;
      private Set <string>handicaps;
      
      public ExtendedEntityPropertiesPlayer(EntityPlayer player)
      {
      this.player = player;
      healthRegenState = false;
      strengthState = false;
      agilityState = false;
      this.handicaps = new HashSet<string>();
      }
      
      @Override
      public void saveNBTData(NBTTagCompound compound) 
      {
      NBTTagCompound properties = new NBTTagCompound();
      properties.setBoolean("healthRegenState", this.healthRegenState);
      properties.setBoolean("strengthState", this.strengthState);
      properties.setBoolean("agilityState", this.agilityState);
      if(handicaps != null)
      {
      NBTTagList list = new NBTTagList();
      for(String current : this.handicaps)
      {
      list.appendTag(new NBTTagString(current));
      }
      properties.setTag("handicaps", list);
      }
      compound.setTag(EXT_PROP_NAME, properties);
      }
      
      @Override
      public void loadNBTData(NBTTagCompound compound) 
      {
      NBTTagCompound properties = (NBTTagCompound) compound.getTag(EXT_PROP_NAME);
      this.healthRegenState = properties.getBoolean("healthRegenState");
      this.strengthState = properties.getBoolean("strengthState");
      this.agilityState = properties.getBoolean("agilityState");
      NBTTagList list = properties.getTagList("handicaps", Constants.NBT.TAG_STRING);
      for(int i = 0; i < list.tagCount(); i++)
      {
      this.handicaps.add(list.getStringTagAt(i));
      }
      }
      
      @Override
      public void init(Entity entity, World world) 
      {
      
      }
      
      public static final void register(EntityPlayer player) 
      {
      player.registerExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME, new ExtendedEntityPropertiesPlayer(player));
      }
      
      public static final ExtendedEntityPropertiesPlayer get(EntityPlayer player) 
      {
      return (ExtendedEntityPropertiesPlayer) player.getExtendedProperties(EXT_PROP_NAME);
      }
      
      public final void sync() 
      {
      PacketGeneticModifierHealth packetModifVie = new PacketGeneticModifierHealth(this.healthRegenState);
      PacketGeneticModifierStrength packetModifAttack = new PacketGeneticModifierStrength(this.strengthState);
      PacketGeneticModifierAgility packetAgility = new PacketGeneticModifierAgility(this.agilityState);
      PacketUpdateHandicap packetHandicap = new PacketUpdateHandicap(this.handicaps);
      DICraftMod.network.sendToServer(packetModifVie);
      DICraftMod.network.sendToServer(packetModifAttack);
              DICraftMod.network.sendToServer(packetAgility);
              DICraftMod.network.sendToServer(packetHandicap);
      if (!player.worldObj.isRemote) 
      {
      EntityPlayerMP player1 = (EntityPlayerMP) player;
      DICraftMod.network.sendTo(packetModifVie, player1);
      DICraftMod.network.sendTo(packetModifAttack, player1);
      DICraftMod.network.sendTo(packetAgility, player1);
      DICraftMod.network.sendTo(packetHandicap, player1);
      }
      }
      
      private static String getSaveKey(EntityPlayer player) 
      {
      return player.getDisplayName() + ":" + EXT_PROP_NAME;
      }
      
      public static void saveProxyData(EntityPlayer player) 
      {
      ExtendedEntityPropertiesPlayer playerData = ExtendedEntityPropertiesPlayer.get(player);
      NBTTagCompound savedData = new NBTTagCompound();
      playerData.saveNBTData(savedData);
      CommonProxy.storeEntityData(getSaveKey(player), savedData);
      }
      
      public static void loadProxyData(EntityPlayer player) 
      {
      ExtendedEntityPropertiesPlayer playerData = ExtendedEntityPropertiesPlayer.get(player);
      NBTTagCompound savedData = CommonProxy.getEntityData(getSaveKey(player));
      if (savedData != null) 
      {
      playerData.loadNBTData(savedData);
      }
      playerData.sync();
      }
      
      public boolean getHealthRegenState() 
      {
      return healthRegenState;
      }
      
      public void changeHealthRegenStateInADN(boolean newHealthRegenState) 
      {
      this.healthRegenState = newHealthRegenState;
      this.sync();
      }
      
      public void changeHealthRegenStateInADNWithoutSync(boolean newHealthRegenState) 
      {
      this.healthRegenState = newHealthRegenState;
      }
      
      public boolean getStrengthState() 
      {
      return strengthState;
      }
      
      public void changeStrengthStateInADN(boolean newStrengthState) 
      {
      this.strengthState = newStrengthState;
      this.sync();
      }
      
      public void changeStrengthStateInADNWithoutSync(boolean newStrengthState) 
      {
      this.strengthState = newStrengthState;
      }
      
      public boolean getAgilityState() 
      {
      return agilityState;
      }
      
      public void changeAgilityStateInADN(boolean newAgilityState) 
      {
      this.agilityState = newAgilityState;
      this.sync();
      }
      
      public void changeAgilityStateInADNWithoutSync(boolean newAgilityState) 
      {
      this.agilityState = newAgilityState;
      }
      
      public void addHandicap(EnumPlayerHandicaps handicapToAdd)
      {
      this.handicaps.add(handicapToAdd.toString());
      this.sync();
      }
      
      public void removeHandicap(EnumPlayerHandicaps handicapToRemove)
      {
      this.handicaps.remove(handicapToRemove.toString());
      this.sync();
      }
      
      public Set <string>getHandicapsSet()
      {
      return handicaps;
      }
      
      public boolean hasSpecificHandicap(EnumPlayerHandicaps handicap)
      {
      return this.handicaps.contains(handicap.toString());
      }
      
      public void setNewHandicapsSet(Set <string>newOne)
      {
      this.handicaps = newOne;
      }
      
      public enum EnumPlayerHandicaps
      {
      KNOCKEDDOWN
      }
      }
      
      

      Mon packet :

      
      import java.util.ArrayList;
      import java.util.Set;
      
      import cpw.mods.fml.common.network.ByteBufUtils;
      import cpw.mods.fml.common.network.simpleimpl.IMessage;
      import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
      import cpw.mods.fml.common.network.simpleimpl.MessageContext;
      import cpw.mods.fml.relauncher.Side;
      import cpw.mods.fml.relauncher.SideOnly;
      import io.netty.buffer.ByteBuf;
      import net.minecraft.client.Minecraft;
      import net.minecraft.entity.player.EntityPlayer;
      
      public class PacketUpdateHandicap implements IMessage
      {
      private static Set <string>handicaps;
      
      public PacketUpdateHandicap()
      {
      }
      
      public PacketUpdateHandicap(Set <string>handicaps)
      {
      this.handicaps = handicaps;
      }
      
      @Override
      public void fromBytes(ByteBuf buf) 
      {
      for(String current : handicaps)
      {
      this.handicaps.add(ByteBufUtils.readUTF8String(buf));
      }
      }
      
      @Override
      public void toBytes(ByteBuf buf) 
      {
      for(String current : handicaps)
      {
      ByteBufUtils.writeUTF8String(buf, current);
      }
      }
      
      public static class ClientHandler implements IMessageHandler <packetupdatehandicap, imessage="">{
      @Override
      @SideOnly(Side.CLIENT)
      public IMessage onMessage(PacketUpdateHandicap message, MessageContext ctx) 
      {
      EntityPlayer player = Minecraft.getMinecraft().thePlayer;
      ExtendedEntityPropertiesPlayer props = ExtendedEntityPropertiesPlayer.get(player);
      props.setNewHandicapsSet(message.handicaps);
      return null;
      }
      }
      public static class CommonHandler implements IMessageHandler <packetupdatehandicap, imessage="">{
      @Override
      public IMessage onMessage(PacketUpdateHandicap message, MessageContext ctx) 
      {
      EntityPlayer player = Minecraft.getMinecraft().thePlayer;
      ExtendedEntityPropertiesPlayer props = ExtendedEntityPropertiesPlayer.get(player);
      props.setNewHandicapsSet(message.handicaps);
      return null;
      }
      }
      }
      
      

      Et enfin mon EventHandler (pas sûr que ce soit la cause du problème, mais bon…) :

      
      import cpw.mods.fml.common.eventhandler.SubscribeEvent;
      import net.minecraft.entity.monster.EntityCaveSpider;
      import net.minecraft.entity.monster.EntityCreeper;
      import net.minecraft.entity.monster.EntityEnderman;
      import net.minecraft.entity.monster.EntitySilverfish;
      import net.minecraft.entity.monster.EntitySkeleton;
      import net.minecraft.entity.monster.EntitySlime;
      import net.minecraft.entity.monster.EntitySpider;
      import net.minecraft.entity.monster.EntityWitch;
      import net.minecraft.entity.monster.EntityZombie;
      import net.minecraft.entity.passive.EntityBat;
      import net.minecraft.entity.passive.EntityHorse;
      import net.minecraft.entity.passive.EntityOcelot;
      import net.minecraft.entity.passive.EntitySheep;
      import net.minecraft.entity.passive.EntitySquid;
      import net.minecraft.entity.passive.EntityWolf;
      import net.minecraft.entity.player.EntityPlayer;
      import net.minecraft.nbt.NBTTagCompound;
      import net.minecraftforge.event.entity.EntityEvent.EntityConstructing;
      import net.minecraftforge.event.entity.EntityJoinWorldEvent;
      import net.minecraftforge.event.entity.living.LivingDeathEvent;
      
      public class ExtPropEventHandler
      {
      
      private CommonProxy commonProxy = new CommonProxy();
      
      @SubscribeEvent
      public void livingEntity(LivingUpdateEvent event) 
      {
      if (event.entityLiving instanceof EntityPlayer) 
      {
      EntityPlayer player = ((EntityPlayer)event.entityLiving);
      
      ExtendedEntityPropertiesPlayer props = ExtendedEntityPropertiesPlayer.get(player);
      if(player.worldObj.getTotalWorldTime() % 40 == 0)
      {
      if(props.hasSpecificHandicap(EnumPlayerHandicaps.KNOCKEDDOWN))
      props.removeHandicap(EnumPlayerHandicaps.KNOCKEDDOWN);
      else
      props.addHandicap(EnumPlayerHandicaps.KNOCKEDDOWN);
      System.out.println(player.worldObj.isRemote);
      System.out.println(props.getHandicapsSet().size());
      }
      }
      }
      
      @SubscribeEvent
      public void onEntityConstructing(EntityConstructing event) 
      {
      if (event.entity instanceof EntityPlayer && ExtendedEntityPropertiesPlayer.get((EntityPlayer) event.entity) == null)
      ExtendedEntityPropertiesPlayer.register((EntityPlayer) event.entity);
      }
      
      @SubscribeEvent
      public void onLivingDeathEvent(LivingDeathEvent event) 
      {
      if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) 
      {
      NBTTagCompound playerData = new NBTTagCompound();
      ((ExtendedEntityPropertiesPlayer) (event.entity.getExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME))).saveNBTData(playerData);
      commonProxy.storeEntityData(((EntityPlayer) event.entity).getDisplayName(), playerData);
      ExtendedEntityPropertiesPlayer.saveProxyData((EntityPlayer) event.entity);
      } 
      else 
      {
      
      }
      }
      
      @SubscribeEvent
      public void onEntityJoinWorld(EntityJoinWorldEvent event) 
      {
      if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) 
      {
      NBTTagCompound playerData = commonProxy .getEntityData(((EntityPlayer) event.entity) .getDisplayName());
      if (playerData != null) 
      {
      ((ExtendedEntityPropertiesPlayer) (event.entity.getExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME))).loadNBTData(playerData);
      }
      ((ExtendedEntityPropertiesPlayer) (event.entity.getExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME))).sync();
      }
      }
      }
      
      

      Et enfin les lignes d’enregistrement de mes packets dans ma classe principale :
      network.registerMessage(PacketUpdateHandicap.ClientHandler.class, PacketUpdateHandicap.class, 7, Side.CLIENT);
      network.registerMessage(PacketUpdateHandicap.CommonHandler.class, PacketUpdateHandicap.class, 8, Side.SERVER);

      Voilà, j’espère que rien ne manque, merci d’avance =)</packetupdatehandicap,></packetupdatehandicap,></string></string></string></string></string></string>

      1 réponse Dernière réponse Répondre Citer 0
      • robin4002R Hors-ligne
        robin4002 Moddeurs confirmés Rédacteurs Administrateurs
        dernière édition par

        Salut,
        Le problème vient de ton paquet, la boucle qui fait la lecture ne fait rien car handicaps est null.
        Il faudrait plutôt faire comme ça :

        @Override
        public void fromBytes(ByteBuf buf)
        {
           int size = buf.readInt()
           handicaps = new HashSet<string>();
           for(int i = 0; i < size; i++)
           {
               this.handicaps.add(ByteBufUtils.readUTF8String(buf));
           }
        }
        
        @Override
        public void toBytes(ByteBuf buf)
        {
           buf.writeInt(handicaps.size());
           for(String current : handicaps)
           {
               ByteBufUtils.writeUTF8String(buf, current);
           }
        }
        ```</string>
        1 réponse Dernière réponse Répondre Citer 0
        • DeletedD Hors-ligne
          Deleted
          dernière édition par

          Ce que je ne comprends pas, c’est que la variable handicaps est initialisée dans le constructeur, pourquoi faut-il le refaire encore une fois dans fromBytes() ??

          1 réponse Dernière réponse Répondre Citer 0
          • robin4002R Hors-ligne
            robin4002 Moddeurs confirmés Rédacteurs Administrateurs
            dernière édition par

            Elle est initialisé dans le constructeur public PacketUpdateHandicap(Set <string>handicaps), ce constructeur est utilisé pour l’envoie du paquet.
            à la réception du paquet c’est le constructeur public PacketUpdateHandicap() qui est utilisé (d’où la nécessité d’avoir toujours un constructeur vide).
            Lors de la réception les données n’ont pas encore été lu, donc forcement il ne connait pas encore les variables.
            Les variables prennent leurs valeurs lorsque la méthode fromBytes est lu.</string>

            1 réponse Dernière réponse Répondre Citer 0
            • DeletedD Hors-ligne
              Deleted
              dernière édition par

              Merci je comprends mieux. Pour le moment ça fixe le bug des valeurs non changeantes, mais désormais le client a toujours une valeur opposée à celle du serveur. Genre quand mon client est à true, le serveur est à false, et le coup prochain, c’est le contraire 😕
              C’est à croire que la méthode sync() fait mal son boulot, ou encore que le packet a des handlers buggués ?
              Dans chaque handler, je redéfinis à la fin le set de l’ExtProp avec celui reçu dans mon message, est-ce le bon moyen ou aurais-je dû faire autrement ??

              1 réponse Dernière réponse Répondre Citer 0
              • robin4002R Hors-ligne
                robin4002 Moddeurs confirmés Rédacteurs Administrateurs
                dernière édition par

                Peux-tu envoyer le paquet qui gère les booleans ? Car dans le paquet tu as envoyé il n’y a que le set qui est synchronisé.

                1 réponse Dernière réponse Répondre Citer 0
                • DeletedD Hors-ligne
                  Deleted
                  dernière édition par

                  En fait il n’y a pas de packet boolean, si tu regardes bien mon println dans mon EventHandler, LivingUpdateEvent. Je fais juste un petit if(props.hasSpecificHandicap(maEnumValue)).
                  Du coup si le packet avec la HashSet avait bien fonctionné, le client et le serveur seraient censés avoir tous les deux cet objet dans handicaps, ce qui n’est le cas que 1 fois sur 2 😕

                  1 réponse Dernière réponse Répondre Citer 0
                  • robin4002R Hors-ligne
                    robin4002 Moddeurs confirmés Rédacteurs Administrateurs
                    dernière édition par

                    Ah oui d’accord.
                    Je croyais que tu parlais des boolean agilityState, strengthState etc …

                    Faudrait afficher le contenu de ta liste à différent endroit (à la fin de l’handler après avoir reçu le paquet, avant d’envoyer le paquet, etc …) pour trouver vers où est le souci.

                    1 réponse Dernière réponse Répondre Citer 0
                    • DeletedD Hors-ligne
                      Deleted
                      dernière édition par

                      Okay je vais bien debug cet aprèm, et je te renverrai les logs.

                      1 réponse Dernière réponse Répondre Citer 0
                      • DeletedD Hors-ligne
                        Deleted
                        dernière édition par

                        Rebonjour, le problème a l’air corrigé car si je rightclick avec un custom item changeant à chaque fois le contenu de HashSet, eh bien la console m’indique de bons résultats.
                        Bref je passe en résolue, mais j’en profite également pour poser 2 petites questions à part, histoire de ne pas recréer 2 topics différents de 3 messages chacun ^^’

                        1)Pourquoi la variable EntityPlayer#iteminUseCount, n’est-elle pas enregistrée dans les tags du joueur, alors qu’elle est bien unique pour chacun d’entres-eux ?
                        2)Je viens de créer un projectile possédant un delay de 3 sec’s avant d’exploser, je l’ai bien enregistré via EntityRegistry.registerModEntity, idem pour son rendu, mais quand je le lance et que je déco/reco de la map, il disparaît comme si il n’avait jamais été lancé 😕 Sauriez-vous par hasard d’où cela peut venir ??
                        Merci d’avance 😉

                        1 réponse Dernière réponse Répondre Citer 0
                        • robin4002R Hors-ligne
                          robin4002 Moddeurs confirmés Rédacteurs Administrateurs
                          dernière édition par

                          1. Car ça serait inutile ? Enregistrer une variable dans un tag nbt permet de l’enregistrer sur le disque et donc de ne pas la perdre lorsqu’elle est supprimé de la ram (principalement quand le serveur / client est coupé). Aucun intérêt à rendre iteminUseCount persistant.

                          2. tu le lances bien côté serveur ?

                          1 réponse Dernière réponse Répondre Citer 0
                          • 1 / 1
                          • Premier message
                            Dernier message
                          Design by Woryk
                          ContactMentions Légales

                          MINECRAFT FORGE FRANCE © 2024

                          Powered by NodeBB