Posted June 12, 20169 yr How should I send data from server to client on player login? I am trying to do this: public void onEntityLoad(AttachCapabilitiesEvent.Entity event) { if (event.getEntity() instanceof EntityPlayer) { event.addCapability(new ResourceLocation(TESItems.attributesTagName), new PlayerAttributesCapabilityProvider()); IPlayerAttributesCapability cap = event.getEntity().getCapability(TESItems.attributesCapability, null); networkWrapper.sendTo(new AttributesMessage(cap.getAttributes()), (EntityPlayerMP) event.getEntity()); System.out.println("onEntityLoad(" + event.getEntity().getDisplayName() + ")"); } , but I get cap == null. Where should I send my packet? Capability works fine on server side, I already used it.
June 12, 20169 yr Capabilities are only attached and read from NBT after AttachCapabilityEvent has been fired. You should send the packet from EntityJoinWorldEvent . To make the capability persist through respawning, subscribe to PlayerEvent.Clone and copy the capability's data from the old player to the new one. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
June 12, 20169 yr Author No, it's still null. Here's my code: @SubscribeEvent public void onEntityJoinWorld(EntityJoinWorldEvent event) { IPlayerAttributesCapability cap = event.getEntity().getCapability(TESItems.attributesCapability, null); if (cap == null) System.out.println("cap == null"); networkWrapper.sendTo(new AttributesMessage(cap.getAttributes()), (EntityPlayerMP) event.getEntity()); }
June 12, 20169 yr EntityJoinWorldEvent is fired for all entities, not just players. Check if the entity is a player before trying to retrieve the capability. If it still doesn't work, post your code. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
June 12, 20169 yr Author There's another problem now. Minecraft#thePlayer here is null: @Override public IMessage onMessage(AttributesMessage message, MessageContext ctx) { System.out.println("got message"); EntityPlayer player = Minecraft.getMinecraft().thePlayer; if (player == null) System.out.println("player == null"); IPlayerAttributesCapability cap = player.getCapability(TESItems.attributesCapability, null); for (String s : TESItems.ATTRIBUTES) { System.out.println("Adding " + s + " to player"); cap.setAttribute(s, message.getAttribute(s)); } return null; }
June 12, 20169 yr http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html Server entity joins world 1st, client moment after that. If you don't apply thread safety, a packet sent from join world event can reach client before client creates its player entity. 1.7.10 is no longer supported by forge, you are on your own.
June 12, 20169 yr Packets are handled on a separate thread in 1.8+, so you need to schedule a task on the main thread before you can safely interact with game objects. This page explains more. If scheduling a task on the main thread doesn't fix this, post your new code. The client player is created and spawned when the client receives SPacketJoinGame from the server. The server sends this before spawning the player, so it should usually be received before a packet sent from EntityJoinWorldEvent . Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
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.