Roboguy99 Posted September 12, 2015 Posted September 12, 2015 I want it so when the player clicks a button, their inventory, and another inventory, are both updated. The code to update the inventory is triggered client-side, so as soon as you try to open the updated inventory it un-updates because the server was unaware of the change. Do I need to write a load of packet-handling code or is there a much easier way of doing this? Quote I have no idea what I'm doing.
Failender Posted September 12, 2015 Posted September 12, 2015 define "update" but yes. i guess u need packets. Quote
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 define "update" but yes. i guess u need packets. Update as in change the the contents of slots. Quote I have no idea what I'm doing.
Failender Posted September 12, 2015 Posted September 12, 2015 I dont know about all vanilla packets out of my head. either u find a vanilla one u can send or u need to create a custom one Quote
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 There is no vanilla packet for this. Ok thanks, I will create one then. Quote I have no idea what I'm doing.
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 Ok I've created the packet, but I have a couple of problems. Firstly, my packet doesn't actually seem to be received. If I don't initialise InventoryUpdate (the IMessage class) with a string, it throws a nullpointerexception when encoding. If I do pass a string, nothing happens. Secondly, I have no idea how to actually use the packet to update the inventory. Here's the packet class: package roboguy99.hotbarBag.network.packet; import cpw.mods.fml.common.network.ByteBufUtils; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import io.netty.buffer.ByteBuf; public class InventoryUpdate implements IMessage { private String text; public InventoryUpdate() { } public InventoryUpdate(String text) { this.text = text; } @Override public void fromBytes(ByteBuf buf) { this.text = ByteBufUtils.readUTF8String(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeUTF8String(buf, this.text); } public static class Handle implements IMessageHandler<InventoryUpdate, IMessage> { @Override public IMessage onMessage(InventoryUpdate message, MessageContext ctx) { System.out.println("packet recieved"); return null; } } } Quote I have no idea what I'm doing.
Failender Posted September 12, 2015 Posted September 12, 2015 1. Dont use Minecraft.getMinecraft on a server, the class is client side only 2. How is that a packet class? Wheres ur IMessage ,wheres the IMessageHandler, what is this? Quote
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 1. Dont use Minecraft.getMinecraft on a server, the class is client side only 2. How is that a packet class? Wheres ur IMessage ,wheres the IMessageHandler, what is this? uploaded wrong class, whoops I'm changing it now. In answer to part 1 of your reply, that code was client-side. Lesson learned - make sure you paste the right thing before clicking submit. Quote I have no idea what I'm doing.
Failender Posted September 12, 2015 Posted September 12, 2015 to create a message u need to use the constructor with the argu,ments. the empty is for forge. there cant be a npe Quote
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 to create a message u need to use the constructor with the argu,ments. the empty is for forge. there cant be a npe Ok, but as I said with a message nothing happens. Quote I have no idea what I'm doing.
Failender Posted September 12, 2015 Posted September 12, 2015 show the crash log and how u send the packet Quote
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 show the crash log and how u send the packet I'm not getting a crash log - NOTHING is happening. If I don't initialise with a string, I get a nep I am sending the packet using HotbarBag.networkWrapper.sendToAll(new InventoryUpdate("updateInventory")); I have also tried .sendToServer() and got the same result. Quote I have no idea what I'm doing.
Failender Posted September 12, 2015 Posted September 12, 2015 there is NO need to send a string if u dont use it. remove it. Quote
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 there is NO need to send a string if u dont use it. remove it. Ok I've done that and I get this: io.netty.handler.codec.EncoderException: java.lang.NullPointerException at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107) ~[MessageToMessageEncoder.class:?] at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116) ~[MessageToMessageCodec.class:?] at io.netty.channel.DefaultChannelHandlerContext.invokeWrite(DefaultChannelHandlerContext.java:644) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.write(DefaultChannelHandlerContext.java:698) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:688) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:717) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:893) ~[DefaultChannelPipeline.class:?] at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:239) ~[AbstractChannel.class:?] at cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToAll(SimpleNetworkWrapper.java:182) [simpleNetworkWrapper.class:?] at roboguy99.hotbarBag.TickEventHandler.onClientTick(TickEventHandler.java:20) [TickEventHandler.class:?] at cpw.mods.fml.common.eventhandler.ASMEventHandler_22_TickEventHandler_onClientTick_ClientTickEvent.invoke(.dynamic) [?:?] at cpw.mods.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:54) [ASMEventHandler.class:?] at cpw.mods.fml.common.eventhandler.EventBus.post(EventBus.java:138) [EventBus.class:?] at cpw.mods.fml.common.FMLCommonHandler.onPreClientTick(FMLCommonHandler.java:325) [FMLCommonHandler.class:?] at net.minecraft.client.Minecraft.runTick(Minecraft.java:1678) [Minecraft.class:?] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1039) [Minecraft.class:?] at net.minecraft.client.Minecraft.run(Minecraft.java:962) [Minecraft.class:?] at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_80] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_80] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_80] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_80] at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?] at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?] at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?] at GradleStart.main(Unknown Source) [start/:?] Caused by: java.lang.NullPointerException at cpw.mods.fml.common.network.ByteBufUtils.writeUTF8String(ByteBufUtils.java:132) ~[byteBufUtils.class:?] at roboguy99.hotbarBag.network.packet.InventoryUpdate.toBytes(InventoryUpdate.java:32) ~[inventoryUpdate.class:?] at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:11) ~[simpleIndexedCodec.class:?] at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:7) ~[simpleIndexedCodec.class:?] at cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec.encode(FMLIndexedMessageToMessageCodec.java:51) ~[FMLIndexedMessageToMessageCodec.class:?] at io.netty.handler.codec.MessageToMessageCodec$1.encode(MessageToMessageCodec.java:67) ~[MessageToMessageCodec$1.class:?] at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89) ~[MessageToMessageEncoder.class:?] ... 25 more [14:37:36] [Client thread/ERROR] [FML]: SimpleChannelHandlerWrapper exception io.netty.handler.codec.EncoderException: java.lang.NullPointerException at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107) ~[MessageToMessageEncoder.class:?] at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116) ~[MessageToMessageCodec.class:?] at io.netty.channel.DefaultChannelHandlerContext.invokeWrite(DefaultChannelHandlerContext.java:644) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.write(DefaultChannelHandlerContext.java:698) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:688) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.writeAndFlush(DefaultChannelHandlerContext.java:717) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:893) ~[DefaultChannelPipeline.class:?] at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:239) ~[AbstractChannel.class:?] at cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToAll(SimpleNetworkWrapper.java:182) [simpleNetworkWrapper.class:?] at roboguy99.hotbarBag.TickEventHandler.onClientTick(TickEventHandler.java:20) [TickEventHandler.class:?] at cpw.mods.fml.common.eventhandler.ASMEventHandler_22_TickEventHandler_onClientTick_ClientTickEvent.invoke(.dynamic) [?:?] at cpw.mods.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:54) [ASMEventHandler.class:?] at cpw.mods.fml.common.eventhandler.EventBus.post(EventBus.java:138) [EventBus.class:?] at cpw.mods.fml.common.FMLCommonHandler.onPreClientTick(FMLCommonHandler.java:325) [FMLCommonHandler.class:?] at net.minecraft.client.Minecraft.runTick(Minecraft.java:1678) [Minecraft.class:?] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1039) [Minecraft.class:?] at net.minecraft.client.Minecraft.run(Minecraft.java:962) [Minecraft.class:?] at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_80] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_80] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_80] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_80] at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?] at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?] at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?] at GradleStart.main(Unknown Source) [start/:?] Caused by: java.lang.NullPointerException at cpw.mods.fml.common.network.ByteBufUtils.writeUTF8String(ByteBufUtils.java:132) ~[byteBufUtils.class:?] at roboguy99.hotbarBag.network.packet.InventoryUpdate.toBytes(InventoryUpdate.java:32) ~[inventoryUpdate.class:?] at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:11) ~[simpleIndexedCodec.class:?] at cpw.mods.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:7) ~[simpleIndexedCodec.class:?] at cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec.encode(FMLIndexedMessageToMessageCodec.java:51) ~[FMLIndexedMessageToMessageCodec.class:?] at io.netty.handler.codec.MessageToMessageCodec$1.encode(MessageToMessageCodec.java:67) ~[MessageToMessageCodec$1.class:?] at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89) ~[MessageToMessageEncoder.class:?] ... 25 more Quote I have no idea what I'm doing.
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 Show your updated code. The only thing I changed was this line: HotbarBag.networkWrapper.sendToAll(new InventoryUpdate()); I'll upload the rest of the packet related code so you can see that as well: Main class pre-init: this.networkWrapper = NetworkRegistry.INSTANCE.newSimpleChannel("hotbarBag_inv"); this.networkWrapper.registerMessage(Handle.class, InventoryUpdate.class, 0, Side.SERVER); Packet class: package roboguy99.hotbarBag.network.packet; import cpw.mods.fml.common.network.ByteBufUtils; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import io.netty.buffer.ByteBuf; import roboguy99.hotbarBag.HotbarBag; public class InventoryUpdate implements IMessage { private String text; public InventoryUpdate() { } public InventoryUpdate(String text) { this.text = text; } @Override public void fromBytes(ByteBuf buf) { this.text = ByteBufUtils.readUTF8String(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeUTF8String(buf, this.text); } public static class Handle implements IMessageHandler<InventoryUpdate, IMessage> { @Override public IMessage onMessage(InventoryUpdate message, MessageContext ctx) { HotbarBag.logger.info("Inventories successfully updated"); return null; } } } Quote I have no idea what I'm doing.
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 Jesus mercy. Of course this will null-pointer. Why? You are using the no-arg constructor, which does not initialize the text field. Then you send the packet, which writes the text field to the buffer, but the text field is null. Oh wonder, it throws a NPE. This will come across as me being an asshole, but if you cannot figure things like this out on your own, you should not be making a mod. I'm going to sound like some lazy arse programmer who just copies and pastes people's code without understanding, then makes a million excuses in reply, but here's what's happened: I've read and copied the code (I typed, didn't c+p) your tutorial with very little understanding of how the packets work. I was doing something else at the same time, so my attention was only half on programming. Failender told me I should use the constructor with arguments, so I assumed this meant send a string. He then told me to remove the string from the arguments, so I did. By this point I completely forgot that text field existed, and I was checking into this thread every now and then while doing something else. Thanks for the help, and I'll try to be less stupid in the future. It was entirely my fault, and I appreciate that. You guys are very useful, and I didn't mean to waste your time with a really noob mistake like that. EDIT: One last thing, because I'm confused myself silly with all this now. Do I get rid of all references to the string as I don't need it, and leave the fromBytes()/toBytes() blank or do I actually need the string, or something I've also somehow stupidly missed which is so blatantly obvious I need to go and punch a wall? If that sounded like it was against you, it seriously wasn't. I'm angry I didn't spot the text field sooner. Quote I have no idea what I'm doing.
Failender Posted September 12, 2015 Posted September 12, 2015 you dont need to write or read anything from the buffer. if u just need a message that is like "update now!" and u dont need more information go ahead Quote
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 Ok, I've removed all references to the string, and the packet is successfully being received. If I update the inventory from here like I was before, will it work because it's server-side code. If not, how do I actually go about updating the inventory? Quote I have no idea what I'm doing.
Ernio Posted September 12, 2015 Posted September 12, 2015 What type of inventory update are we talking about? You want to change item in slot? Add something? Edit ItemStack? Whos inventory is it - player, entity, chest? Quote 1.7.10 is no longer supported by forge, you are on your own.
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 What type of inventory update are we talking about? You want to change item in slot? Add something? Edit ItemStack? Whos inventory is it - player, entity, chest? Ok yeah, should have explained. I want to change the itemstack in a slot on the player's hotbar and the itemstack in an item's inventory (I can get the item's inventory as long as I have the player). All I'm doing is swapping the two stacks around. Quote I have no idea what I'm doing.
Ernio Posted September 12, 2015 Posted September 12, 2015 How it should be written (according to me ;p) 1. If you are changing currently held itemStack - packet can be literally EMPTY. * On receive (handlerr) you can pull out player (sender) from MessageContext: ctx.getServerHandler().playerEntity * From EntityPlayerMP returned you can get inventory, the slot can be gotten from: ctx.getServerHandler().playerEntity.inventory.currentItem 2. If you are changing others then you need to send "byte slotId" via packet (buffer.write/readByte). * Do as in 1., but use slotId from packet instead of "currentItem". Editing ItemStacks is matter of server-side code, all code (its 1.7.10) can be in handler itself. You just operate on ItemStacks. EDIT Do not make this mistake: Since your handler class is inside packet class, when using data send by packet inside handler, don't use e.g: "this.slotId". Use "message.slotId" - the message is in handler's method. Quote 1.7.10 is no longer supported by forge, you are on your own.
Roboguy99 Posted September 12, 2015 Author Posted September 12, 2015 How it should be written (according to me ;p) 1. If you are changing currently held itemStack - packet can be literally EMPTY. * On receive (handlerr) you can pull out player (sender) from MessageContext: ctx.getServerHandler().playerEntity * From EntityPlayerMP returned you can get inventory, the slot can be gotten from: ctx.getServerHandler().playerEntity.inventory.currentItem 2. If you are changing others then you need to send "byte slotId" via packet (buffer.write/readByte). * Do as in 1., but use slotId from packet instead of "currentItem". Editing ItemStacks is matter of server-side code, all code (its 1.7.10) can be in handler itself. You just operate on ItemStacks. That sounds easy enough; I should be ok from here. Thanks Quote I have no idea what I'm doing.
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.