MFF

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

    Problème avec les "Capabilities"

    Planifier Épinglé Verrouillé Déplacé Résolu 1.12.x
    1.12.2
    12 Messages 3 Publieurs 604 Vues 2 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.
    • Vort3x_V Hors-ligne
      Vort3x_
      dernière édition par

      Bonjour/Bonsoir.

      Comme dit dans le titre j’ai des problèmes avec les “capabilites” de forge,
      lors de la déconnection/reconnexion elle passent de 200 à 0. Je ne sais pas si je suis très clair, voici donc des images illustrant le problème.

      Avant de se déconnecter la valeur est à 200.
      2021-01-02_22.41.52.png

      Et après elle repasse à 0.
      2021-01-02_22.41.56.png

      Je donne également le code de ce petit mod.

      En premier la classe Main:

      @EventHandler
      public void init(FMLInitializationEvent event) {
              CapabilityManager.INSTANCE.register(PlayerData.class, new PlayerDataStorage(), new 
              PlayerDataFactory());
              MinecraftForge.EVENT_BUS.register(this);
      }
      

      En suite la classe de PlayerData:

      public class PlayerData implements ICapabilitySerializable<NBTTagCompound>
      {
      	EntityPlayer p;
      	public int water;
      	 
      	public PlayerData(EntityPlayer p) {
      		this.p = p;
      		this.water = 0;
      	}
      	
      	@Override
      	public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
      		return capability == ExampleMod.data;
      	}
      
      	@Override
      	public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
      		return capability == ExampleMod.data ? (T)this : null;
      	}
      
      	@Override
      	public NBTTagCompound serializeNBT() {
      		NBTTagCompound tag = new NBTTagCompound();
      		tag.setInteger("WATER", this.water);
      		return tag;
      	}
      
      	@Override
      	public void deserializeNBT(NBTTagCompound nbt) {
      		this.water = nbt.getInteger("WATER");
      	}
      }
      

      En suite la classe Factory:

      public class PlayerDataFactory implements Callable<PlayerData>
      {
      	@Override
      	public PlayerData call() throws Exception {
      		return null;
      	}
      }
      

      Et pour finir, la classe Storage:

      public class PlayerDataStorage implements IStorage<PlayerData>
      {
      	@Override
      	public NBTBase writeNBT(Capability<PlayerData> capability, PlayerData instance, EnumFacing side) {
      		return capability.writeNBT(instance, side);
      	}
      
      	@Override
      	public void readNBT(Capability<PlayerData> capability, PlayerData instance, EnumFacing side, NBTBase nbt) {
      		capability.readNBT(instance, side, nbt);
      	}
      }
      

      Quelques infos supplémentaire:
      je me suis basé sur ce tuto en 1.8.9: https://www.minecraftforgefrance.fr/topic/2800/utiliser-les-capabilities.
      Et celui ci en 1.9.4 (sources du tuto) : https://github.com/mchorse/capabilities
      Ainsi que la documentation officiel: https://mcforge.readthedocs.io/en/latest/datastorage/capabilities/

      C’est certainement une erreur stupide de ma part mais je bloque.
      Quoi qu’il en soit, merci de vos réponses.

      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,

        As-tu vérifiés que les fonctions deserializeNBT et serializeNBT sont bien appelé ?

        Vort3x_V 1 réponse Dernière réponse Répondre Citer 0
        • Vort3x_V Hors-ligne
          Vort3x_ @robin4002
          dernière édition par

          @robin4002 Bonjour, merci de cette réponse rapide.

          Alors oui j’ai vérifier qu’elles étaient appelée (avec un System.out.println), et elle le sont bien.

          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

            Et les valeurs sont cohérentes ?

            Vort3x_V 1 réponse Dernière réponse Répondre Citer 0
            • Vort3x_V Hors-ligne
              Vort3x_ @robin4002
              dernière édition par

              @robin4002

              Dans la console, le println donne la bonne valeur pour “serializeNBT”
              serializeNBT.png

              Et dans le “deserializeNBT” le println envoie aussi la bonne valeur.
              deserializeNBT.png

              J’ai également été voir la valeur dans le ForgeCaps via
              “NBTExplorer” elle aussi est à 200.
              Capture d’écran 2021-01-03 162749.png

              C’est ce qui est étrange peut-être un problème de sync Client/Server.

              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

                Oui donc c’est un problème de synchro entre le client et le serveur.

                La valeur est sauvegarder uniquement sur le serveur, pour l’afficher sur le gui il faut un paquet afin de synchroniser la valeur vers le client.

                Vort3x_V 1 réponse Dernière réponse Répondre Citer 0
                • Vort3x_V Hors-ligne
                  Vort3x_ @robin4002
                  dernière édition par

                  @robin4002 Bonsoir,

                  Un paquet de ce style ?

                  public class PacketPlayerData implements IMessage
                  {
                  	private EntityPlayer player;
                  	private int water;
                  	 
                  	public PacketPlayerData() {}
                  	
                  	public PacketPlayerData(EntityPlayer p) {
                  		this.player = p;
                  		PlayerData data = player.getCapability(ExampleMod.data, null);
                  		this.water = data.water;
                  	}
                  	
                      @Override
                      public void fromBytes(ByteBuf buf)
                      {
                      	buf.writeInt(this.water);
                      }
                   
                      @Override
                      public void toBytes(ByteBuf buf)
                      {
                      	water = buf.readInt();
                      }
                      
                      public static class Handler implements IMessageHandler <PacketPlayerData, IMessage>{
                          @Override
                          public IMessage onMessage(PacketPlayerData message, MessageContext ctx)
                          {
                          	PlayerData data = message.player.getCapability(ExampleMod.data, null);
                          	data.water = message.water;
                              return message;
                          }
                      }
                  }
                  

                  ensuite j’ai créé une fonction sync:

                  public void sync()
                  {
                  	PacketPlayerData packet = new PacketPlayerData(this.p);
                  	if(!this.p.world.isRemote)
                  	{
                  	        EntityPlayerMP playerMP = (EntityPlayerMP)p;
                  	        ExampleMod.net.sendTo(packet, playerMP);
                  	 }
                  	 else { ExampleMod.net.sendToServer(packet); }
                  }
                  

                  J’appelle cette fonction dans la fonction setWater(int i)

                  public void setWater(int i)
                  {
                  	this.water = i;
                  	sync();
                  }
                  

                  PS: J’utilisais le même genre de paquets avec les **IExtendedEntityProperties ** en 1.7.10.

                  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

                    Oui c’est ça, mais il faudrait également envoyer ce paquet lors de la premier connexion du joueur afin qu’il récupère la valeur.

                    Vort3x_V 1 réponse Dernière réponse Répondre Citer 0
                    • Vort3x_V Hors-ligne
                      Vort3x_ @robin4002
                      dernière édition par

                      @robin4002 Salut désolé pour cette réponse tardive,
                      je vais essayer tout ça, je tiens informé.

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

                        Bonjour, il y a un problème dans ton packet, tu as pas besoin de passer le joueur en paramètre, tu peux directement passer par Minecraft.getMinecraft().player dans ce cas, parce que le packet est reçu coté client

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

                          Bonbjour/Bonsoir,

                          J’ai donc créé un paquet (ci-dessous).

                          public class PacketPlayerData implements IMessage
                          {
                          	private int water;
                          	 
                          	public PacketPlayerData() {}
                          	
                          	public PacketPlayerData(PlayerData data) {
                          		this.water = data.water;
                          	}
                          	
                              @Override
                              public void fromBytes(ByteBuf buf)
                              {
                              	this.water = buf.readInt();
                              }
                           
                              @Override
                              public void toBytes(ByteBuf buf)
                              {
                              	buf.writeInt(this.water);
                              }
                              
                              public static class Handler implements IMessageHandler <PacketPlayerData, IMessage> {
                              	
                                  @Override
                                  public IMessage onMessage(PacketPlayerData message, MessageContext ctx)
                                  {
                                  	PlayerData data = Minecraft.getMinecraft().player.getCapability(ModEngine.data, null);
                          //Il semblerait que data soit null
                                  	data.water = message.water;
                                      return null;
                                  }
                              }
                          }
                          

                          Ensuite j’ai ma fonction “sync” qui envoie le paquet

                          public void sync()
                          {
                          	PacketPlayerData packet = new PacketPlayerData(this);
                                 if(!this.player.world.isRemote) { ModEngine.mc_network.sendTo(packet, 
                                  (EntityPlayerMP)this.player); }
                          }
                          

                          Sauf que quand cette fonction est appelée (connexion au monde) il me fait cette erreur:

                          java.util.concurrent.ExecutionException: java.lang.NullPointerException
                          	at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_271]
                          	at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_271]
                          	at net.minecraft.util.Util.runTask(Util.java:51) [Util.class:?]
                          	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1088) [Minecraft.class:?]
                          	at net.minecraft.client.Minecraft.run(Minecraft.java:398) [Minecraft.class:?]
                          	at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
                          	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_271]
                          	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_271]
                          	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_271]
                          	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_271]
                          	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
                          	at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
                          	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_271]
                          	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_271]
                          	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_271]
                          	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_271]
                          	at net.minecraftforge.legacydev.Main.start(Main.java:86) [legacydev-0.2.3.1-fatjar.jar:0.2.3.1+4+372be23]
                          	at net.minecraftforge.legacydev.MainClient.main(MainClient.java:29) [legacydev-0.2.3.1-fatjar.jar:0.2.3.1+4+372be23]
                          Caused by: java.lang.NullPointerException
                          	at net.minecraft.client.network.NetHandlerPlayClient.handleWindowItems(NetHandlerPlayClient.java:1187) ~[NetHandlerPlayClient.class:?]
                          	at net.minecraft.network.play.server.SPacketWindowItems.processPacket(SPacketWindowItems.java:59) ~[SPacketWindowItems.class:?]
                          	at net.minecraft.network.play.server.SPacketWindowItems.processPacket(SPacketWindowItems.java:13) ~[SPacketWindowItems.class:?]
                          	at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:15) ~[PacketThreadUtil$1.class:?]
                          	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_271]
                          	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_271]
                          	at net.minecraft.util.Util.runTask(Util.java:50) ~[Util.class:?]
                          	... 15 more
                          [16:36:14] [Client thread/FATAL] [minecraft/Minecraft]: Error executing task
                          
                          1 réponse Dernière réponse Répondre Citer 0
                          • Vort3x_V Hors-ligne
                            Vort3x_
                            dernière édition par

                            Bon j’ai finalement réglé le problème de “capabilities”, je passe donc ce poste en résolu.
                            Encore merci pour vos réponses.

                            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