Bonjour,
Alors voilà mon problème : je n’arrive pas à synchroniser le server et le client pour mon ExtendedProperties : sur le client la propriété se remet à 0 dès qu’on charge le monde, et par contre sur le server pas de soucis ça sauvegarde bien :
:::
Voilà ce que j’obtiens quand je charge un monde et que je demande la valeur de stat :http://www.casimages.com/i/141029015100755129.png
:::
Je vous mets les classes de mon mod :
:::
Classe principale :
| package mc_plus.common; |
| |
| import mc_plus.network.PacketPipeline; |
| import net.minecraft.block.Block; |
| import net.minecraft.item.Item; |
| import net.minecraftforge.common.MinecraftForge; |
| import cpw.mods.fml.common.Mod; |
| import cpw.mods.fml.common.Mod.EventHandler; |
| import cpw.mods.fml.common.Mod.Instance; |
| import cpw.mods.fml.common.SidedProxy; |
| import cpw.mods.fml.common.event.FMLInitializationEvent; |
| import cpw.mods.fml.common.event.FMLPostInitializationEvent; |
| import cpw.mods.fml.common.event.FMLPreInitializationEvent; |
| import cpw.mods.fml.common.registry.GameRegistry; |
| |
| @Mod(modid = "mc_plus", name = "Mc Plus", version = "1.0.0") |
| |
| public class Mc_Plus { |
| |
| @Instance("mc_plus") |
| public static Mc_Plus instance; |
| |
| @SidedProxy(clientSide = "mc_plus.client.ClientProxy", serverSide = "mc_plus.common.CommonProxy") |
| public static CommonProxy proxy; |
| |
| public static final PacketPipeline pipe = new PacketPipeline(); |
| public static int stat = 0; |
| |
| public static Block test; |
| public static Block reset; |
| |
| @EventHandler |
| public void preInit(FMLPreInitializationEvent event) |
| { |
| |
| test = new Test(true).setBlockName("test"); |
| GameRegistry.registerBlock(test, "placer"); |
| reset = new Test(false).setBlockName("reset"); |
| GameRegistry.registerBlock(reset, "reset"); |
| } |
| |
| @EventHandler |
| public void init(FMLInitializationEvent event) |
| { |
| proxy.registerRender(); |
| MinecraftForge.EVENT_BUS.register(new StatEventHandler()); |
| pipe.initialise(); |
| } |
| |
| @EventHandler |
| public void postInit(FMLPostInitializationEvent event) |
| { |
| pipe.postInitialise(); |
| } |
| |
| } |
Classe de l’Extended Properties :
| package mc_plus.common; |
| |
| import mc_plus.network.PacketStat; |
| 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.world.World; |
| import net.minecraftforge.common.IExtendedEntityProperties; |
| |
| public class ExtendedPlayer implements IExtendedEntityProperties { |
| |
| public final static String EXT_PROP_NAME = "ExtendedPlayer"; |
| private EntityPlayer player; |
| private int stat; |
| |
| public ExtendedPlayer(EntityPlayer player) |
| { |
| this.player = player; |
| this.stat = 0; |
| } |
| |
| public static final void register(EntityPlayer player) |
| { |
| player.registerExtendedProperties(ExtendedPlayer.EXT_PROP_NAME, new ExtendedPlayer(player)); |
| } |
| |
| public static final ExtendedPlayer get(EntityPlayer player) |
| { |
| return (ExtendedPlayer) player.getExtendedProperties(EXT_PROP_NAME); |
| } |
| |
| @Override |
| public void saveNBTData(NBTTagCompound compound) |
| { |
| |
| NBTTagCompound properties = new NBTTagCompound(); |
| |
| properties.setInteger("stat", this.stat); |
| |
| |
| |
| |
| compound.setTag(EXT_PROP_NAME, properties); |
| } |
| |
| |
| @Override |
| public void loadNBTData(NBTTagCompound compound) |
| { |
| |
| NBTTagCompound properties = (NBTTagCompound) compound.getTag(EXT_PROP_NAME); |
| |
| |
| this.stat = properties.getInteger("stat"); |
| |
| System.out.println("[TUT PROPS] Stat from NBT: " + this.stat); |
| } |
| |
| @Override |
| public void init(Entity entity, World world) { |
| |
| |
| } |
| |
| public void sync() |
| { |
| { |
| PacketStat paquetPlayer = new PacketStat (this.stat); |
| Mc_Plus.pipe.sendToServer(paquetPlayer); |
| |
| if (!player.worldObj.isRemote) { |
| EntityPlayerMP player1 = (EntityPlayerMP) player; |
| Mc_Plus.pipe.sendTo(paquetPlayer, player1); |
| } |
| |
| } |
| |
| } |
| |
| public static String getSaveKey(EntityPlayer player) |
| { |
| return player.getDisplayName() + ":" + EXT_PROP_NAME; |
| } |
| |
| public static void saveProxyData(EntityPlayer player) { |
| |
| ExtendedPlayer playerData = ExtendedPlayer.get(player); |
| NBTTagCompound savedData = new NBTTagCompound(); |
| |
| playerData.saveNBTData(savedData); |
| CommonProxy.storeEntityData(getSaveKey(player), savedData); |
| } |
| |
| public static void loadProxyData(EntityPlayer player) { |
| |
| ExtendedPlayer playerData = ExtendedPlayer.get(player); |
| NBTTagCompound savedData = CommonProxy.getEntityData(getSaveKey(player)); |
| |
| if (savedData != null) { |
| playerData.loadNBTData(savedData); |
| } |
| playerData.sync(); |
| } |
| public int getStat() |
| { |
| return this.stat; |
| |
| } |
| public void setStat(int i) |
| { |
| this.stat = i; |
| this.sync(); |
| } |
| public void incrStat() |
| { |
| this.stat++; |
| this.sync(); |
| } |
| public void decrStat() |
| { |
| if (this.stat > 0) |
| this.stat–; |
| this.sync(); |
| } |
| } |
Classe des events :
| package mc_plus.common; |
| |
| import net.minecraft.entity.player.EntityPlayer; |
| import net.minecraft.init.Items; |
| import net.minecraft.item.ItemStack; |
| import net.minecraft.nbt.NBTTagCompound; |
| import net.minecraft.util.ChatComponentTranslation; |
| import net.minecraftforge.event.entity.EntityEvent.EntityConstructing; |
| import net.minecraftforge.event.entity.EntityJoinWorldEvent; |
| import net.minecraftforge.event.entity.living.LivingDeathEvent; |
| import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; |
| import cpw.mods.fml.common.eventhandler.SubscribeEvent; |
| |
| public class StatEventHandler { |
| |
| @SubscribeEvent |
| public void onEntityConstructing(EntityConstructing event) { |
| |
| if (event.entity instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer) event.entity) == null) |
| ExtendedPlayer.register((EntityPlayer) event.entity); |
| } |
| |
| @SubscribeEvent |
| public void onLivingDeathEvent(LivingDeathEvent event) { |
| if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) { |
| NBTTagCompound playerData = new NBTTagCompound(); |
| ((ExtendedPlayer) (event.entity.getExtendedProperties(ExtendedPlayer.EXT_PROP_NAME))).saveNBTData(playerData); |
| CommonProxy.storeEntityData(((EntityPlayer) event.entity).getDisplayName(), playerData); |
| ExtendedPlayer.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) { |
| ((ExtendedPlayer) (event.entity.getExtendedProperties(ExtendedPlayer.EXT_PROP_NAME))).loadNBTData(playerData); |
| } |
| |
| ((ExtendedPlayer) (event.entity.getExtendedProperties(ExtendedPlayer.EXT_PROP_NAME))).sync(); |
| } |
| } |
| |
| @SubscribeEvent |
| public void onUpdate(LivingUpdateEvent event) |
| { |
| |
| if(event.entity instanceof EntityPlayer) |
| { |
| EntityPlayer player = (EntityPlayer) event.entity; |
| ItemStack heldItem = player.getHeldItem(); |
| ExtendedPlayer props = ExtendedPlayer.get(player); |
| |
| int stat = props.getStat(); |
| |
| if(heldItem != null && heldItem.getItem() == Items.gold_ingot) |
| { |
| if(!player.worldObj.isRemote) |
| { |
| player.addChatMessage(new ChatComponentTranslation("[SERVER] : Stat : " + stat)); |
| } |
| else |
| { |
| player.addChatMessage(new ChatComponentTranslation("[CLIENT] : Stat : " + stat)); |
| |
| } |
| } |
| if(heldItem != null && heldItem.getItem() == Items.diamond) |
| { |
| props.incrStat(); |
| } |
| |
| if(stat > 10) |
| { |
| player.capabilities.allowFlying = true; |
| if(heldItem != null && heldItem.getItem() == Items.iron_ingot) |
| { |
| player.addChatMessage(new ChatComponentTranslation("Je peux voler !")); |
| } |
| |
| } |
| else |
| { |
| player.capabilities.allowFlying = false; |
| if(heldItem != null && heldItem.getItem() == Items.iron_ingot) |
| { |
| player.addChatMessage(new ChatComponentTranslation("Je peux pas voler !")); |
| |
| } |
| } |
| |
| } |
| } |
| } |
Je pense que c’est un problème de paquets, je vous mets donc les classes concernant les paquets :
J’ai pris ces classes sur le wiki de forge :http://www.minecraftforge.net/wiki/Netty_Packet_Handling
Classe de AbstractPacket :
| package mc_plus.network; |
| |
| import io.netty.buffer.ByteBuf; |
| import io.netty.channel.ChannelHandlerContext; |
| import net.minecraft.entity.player.EntityPlayer; |
| |
| public abstract class AbstractPacket { |
| public abstract void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer); |
| |
| |
| |
| |
| |
| |
| |
| public abstract void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer); |
| |
| |
| |
| |
| |
| |
| public abstract void handleClientSide(EntityPlayer player); |
| |
| |
| |
| |
| |
| |
| public abstract void handleServerSide(EntityPlayer player); |
| } |
Classe de PacketPipeline :
| package mc_plus.network; |
| |
| import io.netty.buffer.ByteBuf; |
| import io.netty.buffer.Unpooled; |
| import io.netty.channel.ChannelHandler; |
| import io.netty.channel.ChannelHandlerContext; |
| import io.netty.handler.codec.MessageToMessageCodec; |
| |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.EnumMap; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import net.minecraft.client.Minecraft; |
| import net.minecraft.entity.player.EntityPlayer; |
| import net.minecraft.entity.player.EntityPlayerMP; |
| import net.minecraft.network.INetHandler; |
| import net.minecraft.network.NetHandlerPlayServer; |
| import cpw.mods.fml.common.FMLCommonHandler; |
| import cpw.mods.fml.common.network.FMLEmbeddedChannel; |
| import cpw.mods.fml.common.network.FMLOutboundHandler; |
| import cpw.mods.fml.common.network.NetworkRegistry; |
| import cpw.mods.fml.common.network.internal.FMLProxyPacket; |
| import cpw.mods.fml.relauncher.Side; |
| import cpw.mods.fml.relauncher.SideOnly; |
| |
| |
| |
| |
| |
| |
| @ChannelHandler.Sharable |
| public class PacketPipeline extends MessageToMessageCodec <fmlproxypacket, abstractpacket="">{ |
| |
| private EnumMap <side, fmlembeddedchannel="">channels; |
| private LinkedList<class<? extends="" abstractpacket="">> packets = new LinkedList<class<? extends="" abstractpacket="">>(); |
| private boolean isPostInitialised = false; |
| |
| |
| |
| |
| |
| |
| |
| |
| public boolean registerPacket(Class clazz) { |
| if (this.packets.size() > 256) { |
| |
| return false; |
| } |
| |
| if (this.packets.contains(clazz)) { |
| |
| return false; |
| } |
| |
| if (this.isPostInitialised) { |
| |
| return false; |
| } |
| |
| this.packets.add(clazz); |
| return true; |
| } |
| |
| |
| @Override |
| protected void encode(ChannelHandlerContext ctx, AbstractPacket msg, List <object>out) throws Exception { |
| ByteBuf buffer = Unpooled.buffer(); |
| Class clazz = msg.getClass(); |
| if (!this.packets.contains(msg.getClass())) { |
| throw new NullPointerException("No Packet Registered for: " + msg.getClass().getCanonicalName()); |
| } |
| |
| byte discriminator = (byte) this.packets.indexOf(clazz); |
| buffer.writeByte(discriminator); |
| msg.encodeInto(ctx, buffer); |
| FMLProxyPacket proxyPacket = new FMLProxyPacket(buffer.copy(), ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get()); |
| out.add(proxyPacket); |
| } |
| |
| |
| @Override |
| protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List <object>out) throws Exception { |
| ByteBuf payload = msg.payload(); |
| byte discriminator = payload.readByte(); |
| Class clazz = this.packets.get(discriminator); |
| if (clazz == null) { |
| throw new NullPointerException("No packet registered for discriminator: " + discriminator); |
| } |
| |
| AbstractPacket pkt = clazz.newInstance(); |
| pkt.decodeInto(ctx, payload.slice()); |
| |
| EntityPlayer player; |
| switch (FMLCommonHandler.instance().getEffectiveSide()) { |
| case CLIENT: |
| player = this.getClientPlayer(); |
| pkt.handleClientSide(player); |
| break; |
| |
| case SERVER: |
| INetHandler netHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(); |
| player = ((NetHandlerPlayServer) netHandler).playerEntity; |
| pkt.handleServerSide(player); |
| break; |
| |
| default: |
| } |
| |
| out.add(pkt); |
| } |
| |
| |
| public void initialise() { |
| this.channels = NetworkRegistry.INSTANCE.newChannel("TUT", this); |
| } |
| |
| |
| |
| public void postInitialise() { |
| if (this.isPostInitialised) { |
| return; |
| } |
| |
| this.isPostInitialised = true; |
| Collections.sort(this.packets, new Comparator<class<? extends="" abstractpacket="">>() { |
| |
| @Override |
| public int compare(Class clazz1, Class clazz2) { |
| int com = String.CASE_INSENSITIVE_ORDER.compare(clazz1.getCanonicalName(), clazz2.getCanonicalName()); |
| if (com == 0) { |
| com = clazz1.getCanonicalName().compareTo(clazz2.getCanonicalName()); |
| } |
| |
| return com; |
| } |
| }); |
| } |
| |
| @SideOnly(Side.CLIENT) |
| private EntityPlayer getClientPlayer() { |
| return Minecraft.getMinecraft().thePlayer; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public void sendToAll(AbstractPacket message) { |
| this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL); |
| this.channels.get(Side.SERVER).writeAndFlush(message); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public void sendTo(AbstractPacket message, EntityPlayerMP player) { |
| this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); |
| this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player); |
| this.channels.get(Side.SERVER).writeAndFlush(message); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public void sendToAllAround(AbstractPacket message, NetworkRegistry.TargetPoint point) { |
| this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT); |
| this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); |
| this.channels.get(Side.SERVER).writeAndFlush(message); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public void sendToDimension(AbstractPacket message, int dimensionId) { |
| this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION); |
| this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId); |
| this.channels.get(Side.SERVER).writeAndFlush(message); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public void sendToServer(AbstractPacket message) { |
| this.channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER); |
| this.channels.get(Side.CLIENT).writeAndFlush(message); |
| } |
| } |
Classe de PacketStat :
| package mc_plus.network; |
| |
| import io.netty.buffer.ByteBuf; |
| import io.netty.channel.ChannelHandlerContext; |
| import mc_plus.common.ExtendedPlayer; |
| import net.minecraft.entity.player.EntityPlayer; |
| |
| public class PacketStat extends AbstractPacket { |
| |
| private int stat; |
| |
| public PacketStat(){} |
| |
| public PacketStat(int stat) |
| { |
| this.stat = stat; |
| } |
| |
| @Override |
| public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { |
| buffer.writeInt(stat); |
| |
| } |
| |
| @Override |
| public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { |
| this.stat = buffer.readInt(); |
| |
| } |
| |
| @Override |
| public void handleClientSide(EntityPlayer player) { |
| ExtendedPlayer props = ExtendedPlayer.get(player); |
| props.setStat(this.stat); |
| } |
| |
| @Override |
| public void handleServerSide(EntityPlayer player) { |
| ExtendedPlayer props = ExtendedPlayer.get(player); |
| props.setStat(this.stat); |
| |
| } |
| |
| } |
:::
Voilà, j’espère que vous pourrez me dire où est mon erreur, sachant que le jeu se lance ! 
En tout cas, merci d’avoir pris le temps de lire ! :)</class<?></object></object></class<?></class<?></side,></fmlproxypacket,>