Navigation

    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups

    SOLVED Petit problème Syncro ExtProp HashSet

    1.7.x
    1.7.10
    2
    11
    1469
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Deleted
      Deleted last edited by

      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 Reply Last reply Reply Quote 0
      • robin4002
        robin4002 Administrateurs Rédacteurs Moddeurs confirmés last edited by

        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 Reply Last reply Reply Quote 0
        • Deleted
          Deleted last edited by

          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 Reply Last reply Reply Quote 0
          • robin4002
            robin4002 Administrateurs Rédacteurs Moddeurs confirmés last edited by

            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 Reply Last reply Reply Quote 0
            • Deleted
              Deleted last edited by

              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 Reply Last reply Reply Quote 0
              • robin4002
                robin4002 Administrateurs Rédacteurs Moddeurs confirmés last edited by

                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 Reply Last reply Reply Quote 0
                • Deleted
                  Deleted last edited by

                  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 Reply Last reply Reply Quote 0
                  • robin4002
                    robin4002 Administrateurs Rédacteurs Moddeurs confirmés last edited by

                    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 Reply Last reply Reply Quote 0
                    • Deleted
                      Deleted last edited by

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

                      1 Reply Last reply Reply Quote 0
                      • Deleted
                        Deleted last edited by

                        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 Reply Last reply Reply Quote 0
                        • robin4002
                          robin4002 Administrateurs Rédacteurs Moddeurs confirmés last edited by

                          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 Reply Last reply Reply Quote 0
                          • 1 / 1
                          • First post
                            Last post
                          Design by Woryk
                          Contact / Mentions Légales / Faire un don

                          MINECRAFT FORGE FRANCE © 2018

                          Powered by NodeBB