tripl3dogdare Posted August 13, 2016 Share Posted August 13, 2016 So basically the gist of what I'm trying to do is send a packet from the server to the client to update a couple of simple Capability properties on a specific player. However, the client is not being updated, and it's values are locked at 0. The capability itself seems to work fine, and the packet is being both sent and received... Relevant event handler code: @SubscribeEvent public void onLivingUpdate(LivingUpdateEvent e) { if(e.getEntity() instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)e.getEntity(); checkBuffPairEquipped(player); updatePlayerMana(player); } } private void updatePlayerMana(EntityPlayer player) { IManaHandler mh = player.getCapability(ManaHandler.CAP, null); mh.regenMana(5); mh.updateClient(player); System.out.println(mh.getMana()+","+mh.getMaxMana()); } Mana handler "updateClient" method: public void updateClient(EntityPlayer player) { if(!player.getEntityWorld().isRemote && (mana != lastMana || maxMana != lastMaxMana)) ChuuniMod.network.sendTo(new MessageUpdateClientMana(this), (EntityPlayerMP)player); lastMana = mana; lastMaxMana = maxMana; } Packet class: public class MessageUpdateClientMana implements IMessage { private int mana, maxMana; public MessageUpdateClientMana() {} public MessageUpdateClientMana(IManaHandler mh) { this.mana = mh.getMana(); this.maxMana = mh.getMaxMana(); } public void fromBytes(ByteBuf buf) { mana = ByteBufUtils.readVarInt(buf, 4); maxMana = ByteBufUtils.readVarInt(buf, 4); } public void toBytes(ByteBuf buf) { buf.writeInt(mana); buf.writeInt(maxMana); } public static class Handler implements IMessageHandler<MessageUpdateClientMana, IMessage> { public IMessage onMessage(MessageUpdateClientMana message, MessageContext ctx) { Minecraft.getMinecraft().addScheduledTask(() -> { EntityPlayer player = Minecraft.getMinecraft().thePlayer; IManaHandler mh = player.getCapability(ManaHandler.CAP, null); mh.setMana(message.mana); mh.setMaxMana(message.maxMana); System.out.println("packet recieved!"); }); return null; } } } Long story short, if the player's mana has changed since the last tick I send a packet from the server to the client that should update their client-side mana values, but despite the packet being sent and received properly their mana doesn't update. Any ideas? I'm stumped. Edit: Ok, I'm officially stupid... I changed from the ByteBufUtils read methods to the builtin ones and it worked Quote Github: http://github.com/tripl3dogdare Youtube: http://youtube.com/tripl3dogdare Twitter: http://twitter.com/tripl3dogdare Twitter RP: http://twitter.com/TheWitchesEye Link to comment Share on other sites More sharing options...
Ernio Posted August 13, 2016 Share Posted August 13, 2016 I'd just like to add: * For players use PlayerTickEvent (tick events have phases meaning pick START or END). * Redesign your stuff: - You don't need prev/next (or last/current whatever you call it) variables. - Make setter method that will (if called on server) send packet whenever "valueToSet != current". - I'd also split "mana" and "maxMana" into separate packets (and apply tip above). - You seem to not store EntityPlayer inside Capability (assuming that since you are passing EntityPlayer to #updateClient method) - you could redesign it without passing such args. Quote 1.7.10 is no longer supported by forge, you are on your own. Link to comment Share on other sites More sharing options...
tripl3dogdare Posted August 14, 2016 Author Share Posted August 14, 2016 Thanks for the suggestions! I've been working on it a lot trying to iron out the kinks... and I've hit another block. Everything is now working fine - the client and server are in sync, everything seems to be working properly, except the data isn't saving into the world file. Note: In working on the system, I ended up implementing some of your suggestions, namely using PlayerTickEvent and using a single "dirty" variable instead of the "last***" variables to determine whether an update is necessary. Relevant event handlers: @SubscribeEvent public void addPlayerCapabilities(AttachCapabilitiesEvent.Entity e) { if(e.getEntity() instanceof EntityPlayer) e.addCapability(new ResourceLocation(ChuuniMod.MODID, "ManaHandler"), new ManaHandler()); } @SubscribeEvent public void persistPlayerCapabilities(PlayerEvent.Clone e) { if(e.isWasDeath()) { IManaHandler cnew = e.getEntityPlayer().getCapability(ManaHandler.CAP, null); IManaHandler cold = e.getOriginal().getCapability(ManaHandler.CAP, null); cold.copyTo(cnew); } } @SubscribeEvent public void onPlayerTick(PlayerTickEvent e) { if(e.phase != Phase.END) return; checkBuffPairEquipped(e.player); updatePlayerMana(e.player); } private void updatePlayerMana(EntityPlayer player) { if(!player.worldObj.isRemote) { IManaHandler mh = player.getCapability(ManaHandler.CAP, null); mh.regenMana(mh.getManaRegen()); mh.updateClient(player); } } IManaHandler (includes all the capability/packet code): public interface IManaHandler { public float getMana(); public float getMaxMana(); public float getManaRegen(); public float setMana(float amount); public float setMaxMana(float amount); public float setManaRegen(float amount); public boolean consumeMana(float amount); public boolean regenMana(float amount); public void copyTo(IManaHandler other); public void updateClient(EntityPlayer player); public static class ManaHandler implements IManaHandler, ICapabilitySerializable<NBTTagCompound> { @CapabilityInject(IManaHandler.class) public static final Capability<IManaHandler> CAP = null; private float mana,maxMana, manaRegen; private float lastMana, lastMaxMana, lastManaRegen; private boolean dirty = true; public ManaHandler() { this(0, 250, .25f); } public ManaHandler(float mana, float maxMana, float manaRegen) { this.mana = mana; this.maxMana = maxMana; this.manaRegen = manaRegen; } public float getMana() { return mana; } public float getMaxMana() { return maxMana; } public float getManaRegen() { return manaRegen; } public float setMana(float amount) { dirty = true; return mana = amount; } public float setMaxMana(float amount) { dirty = true; return maxMana = amount; } public float setManaRegen(float amount) { dirty = true; return manaRegen = amount; } public NBTTagCompound get() { return serializeNBT(); } public void set(NBTTagCompound nbt) { deserializeNBT(nbt); } public boolean consumeMana(float amount) { if(mana < amount) return false; setMana(mana-amount); return true; } public boolean regenMana(float amount) { if(mana == maxMana) return false; setMana(Math.min(mana+amount, maxMana)); return true; } public void copyTo(IManaHandler other) { other.setMaxMana(this.getMaxMana()); other.setManaRegen(this.getManaRegen()); } public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == CAP; } public <T> T getCapability(Capability<T> capability, EnumFacing facing) { return capability == CAP ? (T)this : null; } public static IManaHandler instanceFor(EntityPlayer player) { return player.getCapability(CAP, null); } public NBTTagCompound serializeNBT() { NBTTagCompound nbt = new NBTTagCompound(); nbt.setFloat("mana", mana); nbt.setFloat("maxMana", maxMana); nbt.setFloat("manaRegen", manaRegen); return nbt; } public void deserializeNBT(NBTTagCompound nbt) { setMana(nbt.getFloat("mana")); setMaxMana(nbt.getFloat("maxMana")); setManaRegen(nbt.getFloat("manaRegen")); } public void updateClient(EntityPlayer player) { if(!player.getEntityWorld().isRemote) { if(dirty) CommonProxy.network.sendTo(new MessageUpdateClientMana(this), (EntityPlayerMP)player); dirty = false; } } public static class Storage implements IStorage<IManaHandler> { public NBTTagCompound writeNBT(Capability<IManaHandler> capability, IManaHandler instance, EnumFacing side) { return ((ManaHandler)instance).serializeNBT(); } public void readNBT(Capability<IManaHandler> capability, IManaHandler instance, EnumFacing side, NBTBase nbt) { ((ManaHandler)instance).deserializeNBT((NBTTagCompound)nbt); } } } /** Packet used to update client-side capabilities */ public static class MessageUpdateClientMana implements IMessage { private float mana, maxMana, manaRegen; public MessageUpdateClientMana() {} public MessageUpdateClientMana(IManaHandler mh) { this.mana = mh.getMana(); this.maxMana = mh.getMaxMana(); this.manaRegen = mh.getManaRegen(); } public void fromBytes(ByteBuf buf) { mana = buf.readFloat(); maxMana = buf.readFloat(); manaRegen = buf.readFloat(); } public void toBytes(ByteBuf buf) { buf.writeFloat(mana); buf.writeFloat(maxMana); buf.writeFloat(manaRegen); } public static class Handler implements IMessageHandler<MessageUpdateClientMana, IMessage> { public IMessage onMessage(MessageUpdateClientMana message, MessageContext ctx) { Minecraft.getMinecraft().addScheduledTask(() -> { EntityPlayer player = Minecraft.getMinecraft().thePlayer; IManaHandler mh = ManaHandler.instanceFor(player); mh.setMana(message.mana); mh.setMaxMana(message.maxMana); mh.setManaRegen(message.manaRegen); System.out.println("Client: "+message.mana+","+message.maxMana+","+message.manaRegen); }); return null; } } } } CommonProxy (registers packet/capability among other things): public class CommonProxy { public static final SimpleNetworkWrapper network = NetworkRegistry.INSTANCE.newSimpleChannel(ChuuniMod.MODID); public void init() { ChuuniConfig.initServer(); ChuuniConfig.initCommon(); CapabilityManager.INSTANCE.register(IManaHandler.class, new ManaHandler.Storage(), ManaHandler::new); MinecraftForge.EVENT_BUS.register(new ChuuniEventHandler()); registerNetworkPackets(); } private void registerNetworkPackets() { int id = 0; network.registerMessage(MessageUpdateClientMana.Handler.class, MessageUpdateClientMana.class, id++, Side.CLIENT); } } I'm using NBTExplorer to directly track what data is saved, and while everything works fine ingame, the data only saves to the world file about 1/20ish times if that and I have no idea why. Edit: Apparently NBTExplorer being open was screwing with it... FML. Quote Github: http://github.com/tripl3dogdare Youtube: http://youtube.com/tripl3dogdare Twitter: http://twitter.com/tripl3dogdare Twitter RP: http://twitter.com/TheWitchesEye Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.