Résolu Problème avec les "Capabilities"
-
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.
Et après elle repasse à 0.
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. -
Salut,
As-tu vérifiés que les fonctions
deserializeNBT
etserializeNBT
sont bien appelé ? -
@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.
-
Et les valeurs sont cohérentes ?
-
Dans la console, le println donne la bonne valeur pour “serializeNBT”
Et dans le “deserializeNBT” le println envoie aussi la bonne valeur.
J’ai également été voir la valeur dans le ForgeCaps via
“NBTExplorer” elle aussi est à 200.
C’est ce qui est étrange peut-être un problème de sync Client/Server.
-
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.
-
@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.
-
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.
-
@robin4002 Salut désolé pour cette réponse tardive,
je vais essayer tout ça, je tiens informé. -
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 -
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
-
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.