Jump to content

Recommended Posts

Posted

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?

I have no idea what I'm doing.

Posted

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;
	}
}
}

 

I have no idea what I'm doing.

Posted

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.

I have no idea what I'm doing.

Posted

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.

I have no idea what I'm doing.

Posted

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.

I have no idea what I'm doing.

Posted

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

 

I have no idea what I'm doing.

Posted

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;
	}
}
}

 

I have no idea what I'm doing.

Posted

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.

I have no idea what I'm doing.

Posted

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?

I have no idea what I'm doing.

Posted

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?

1.7.10 is no longer supported by forge, you are on your own.

Posted

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.

I have no idea what I'm doing.

Posted

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.

1.7.10 is no longer supported by forge, you are on your own.

Posted

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

I have no idea what I'm doing.

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.