I have a block that rarely ever spawns. Player's stats depend on how close they are to this block.
Now to get to the problem. There can be upwards to 100 of these blocks and the server will be calculating how close each and every single player is to the closest block. (So it has to go through all 100 to figure out which is closest. I haven't worked on improving how efficient it is yet, but I will, so lets ignore that part)
I would prefer the client player to determine how close they are, and then send a packet letting the server side know how close they are so that the server can calculate the stats that need to be changed for the player.
I'm working on a way to send the message to the server, I just don't know what to put in "onMessage."
public class updateDistance implements IMessage{
public int distance;
public updateDistance(){}
public updateDistance(int distance){
this.distance = distance;
}
@Override
public void fromBytes(ByteBuf buf) {
distance = ByteBufUtils.readVarInt(buf, 4);
}
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeVarInt(buf, distance, 4);
}
public static class HandleUpdateDistance implements IMessageHandler<updateDistance, IMessage>{
@Override
public IMessage onMessage(updateDistance message, MessageContext ctx){
//What do I put here?
return null;
}
}
}
@atijaf Why would you prefer the client player? That makes no sense - the server side player is equally if not more valid to use, as that has the player's 'real' position in the world. Simply calculate it directly - you shouldn't need any packets at all.
I had a feeling that calculating the closest block to each player would be a resource hog... I was also wanting to understand how to send instructions, as I have multiple uses for sending a packet with instructions.
Rollback Post to RevisionRollBack
I complicate easy problems, come begging for help, and leave with a simple solution.
I had a feeling that calculating the closest block to each player would be a resource hog... I was also wanting to understand how to send instructions, as I have multiple uses for sending a packet with instructions.
It's only a resource hog if you design it that way, and if it is it will be so no matter which side you do it on. Whenever you have a design that is a resource hog, that's a big clue that you may want to re-think your approach. Sometimes it is the only way, but often you can find more optimal solutions, especially if you are willing to alter your design (e.g. only check for blocks within a certain radius of each player, rather than searching for all of them in the world [which is impossible, btw, unless you have a very small and fixed-size world]).
As for 'sending instructions' - what do you mean by that? Packets can send only bytes of information, so whatever you can store in bytes (e.g. integers, Strings, NBT, objects encoded into primitive types, etc.), you can send via packet. That is, you can only send information. What you do with that information is up to you, and you can do anything you want.
In other words, I think of the packet handler as containing all of the instructions, but it needs information from the packet in order to do anything meaningful. You don't 'send' instructions, you write instructions into your packet handler to process information it receives.
I am now on a new problem. I have a gui and am working to have a scrolling bar within it.
I override mouseClickMove from within GuiContainer so that when I move my mouse and left click, a variable changes. The only problem is that this method is a client side only method. (Or at least it doesn't update on the server)
So I need to send a packet to the server telling what row the player is on, but I'm unsure how to obtain the instance of the container i'm using. Here is all the relative code.
I'm not sure what you're trying to do - what is this 'row' for? Is it for the scrollbar? If so, why do you need to send a packet - are you saving the player's position in the scrollbar for the next time they open the GUI? That's the only reason I can think of that you would send a packet for a scrollbar.
Please watch VSWE's Climbing the Interface Ladder tutorials. They will help you immensely in creating a dynamic GUI.
umm, not certain why this is happening, but I made a packet to send some booleans to my server, because the booleans are toggled by keybinds, spent a couple hours trying to figure out why the packet wasn't sending, then realized that i had accidentally set it to send it to the client. I switched it to send to server, and then started getting this error.
[21:44:25] [Netty Server IO #1/ERROR]: SimpleChannelHandlerWrapper exception
java.lang.ClassCastException: com.kookyboy9.wheeloftimemod.packets.SyncPlayerPropsMessage cannot be cast to com.kookyboy9.wheeloftimemod.packets.SyncPlayerPropsFromClient
at com.kookyboy9.wheeloftimemod.packets.SyncPlayerPropsFromClient$SyncPlayerPropsFromClientMessageHandler.handleServerMessage(SyncPlayerPropsFromClient.java:1) ~[SyncPlayerPropsFromClient$SyncPlayerPropsFromClientMessageHandler.class:?]
at com.kookyboy9.wheeloftimemod.packets.AbstractMessageHandler.onMessage(AbstractMessageHandler.java:62) ~[AbstractMessageHandler.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:37) ~[SimpleChannelHandlerWrapper.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:17) ~[SimpleChannelHandlerWrapper.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) ~[SimpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [MessageToMessageDecoder.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) [MessageToMessageCodec.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) [EmbeddedChannel.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:79) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:136) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:414) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [SimpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:409) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:237) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:50) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [SimpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:312) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:44) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel$6.run(LocalChannel.java:298) [LocalChannel$6.class:4.0.15.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354) [SingleThreadEventExecutor.class:4.0.15.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353) [NioEventLoop.class:4.0.15.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [SingleThreadEventExecutor$2.class:4.0.15.Final]
at java.lang.Thread.run(Thread.java:744) [?:1.7.0_51]
any idea whats going on?
edit:this happens after starting a world, just before it is possible to do anything, and just before the world generates in your client.
You probably registered another packet with the same ID, which is why I suggest making a helper method that automatically tracks and increments the IDs for you so you never have to think about it.
Each packet needs to be registered somewhere that is called on both client and server, and each packet class should use the same ID if registering it to be handled on both sides.
// this code gets called from somewhere like your main mod class - don't put any packet registrations in the ClientProxy!
id = 0;
yourChannel.registerMessage(PacketClassOne.class, handler, id, Side.SERVER);
yourChannel.registerMessage(PacketClassOne.class, handler, id, Side.CLIENT); // use same id as above, since it's the same class
id++; // different packet class now
yourChannel.registerMessage(PacketClassTwo.class, handler, id, Side.SERVER);
Note that for the sake of brevity the example above does not use automated IDs or specify a real IMessageHandler.
my packets are called from my main mod class, and when i made the above modifications, they stopped crashing, but now for no apparent reason they only send once in a while.
here is the code in each of my classes, seperated by lines of /s
1. You copied the code from my IEEP tutorial, meaning you have some outdated stuff in there (e.g. saveProxyData, which is deprecated in favor of using PlayerEvent.Clone, and you didn't change the EXT_PROP_NAME string value to something unique). Part of this isn't your fault, since the tutorial has not been updated due to forum editor issues. I recommend you read the tutorial on Github via the link above - they don't have editor issues.
2. You are updating server-side data with data from the client. This is a VERY bad idea. Only the server should be sending updates.
3. #serversideNBTSave and #loadServerSide both seem like really bad ideas, both for reason #2 above, and the way you've written it you will have to change the methods any time you want to add or remove a variable. Why not either a. use the already-available save/load NBT methods, or b. create a class to encapsulate your specific data that you need to update frequently, and give that class save/load NBT methods? It could even just be the IMessage class itself that you pass to the method so you don't have to change the parameters all the time.
4. You don't need to register every method to be handled on both sides; only register it with the Side that it is going to be sent to. 99% of packets are sent to only one side or the other, not both.
5. Your KeepSynchronizedEvent code... no. Why are you sending updates to both sides every single tick? Don't send updates unless something has changed. Also see #2. What do you expect to happen when the server sends its version to the client, and the client sends its version to the server? If they have different data, they will just keep swapping back and forth between the two. See #2.
Send updates directly from a method in which something changes, preferably a message that sends only what needs to be sent (e.g. UpdateCastingMessage, or put all your booleans in an array and send the array index to set along with the value, then you can have a generalized message class). That's one of the main reasons for setter methods.
Is that what all those boolean fields are for? Typically, you send 'key {code} was pressed' to the server, then the server decides what to do with it. E.g. 'key {fire} was pressed', so the server checks if the player can start using fire and, if so, sets the 'fire' boolean value and sends an update packet to the client saying 'fire is now true'.
So: client informs server of key press; server informs client of actual state.
If you're certain that 'fire' will be true after the key press is handled completely by the server, and / or you want to have immediate feedback to the client player (e.g. show which type is selected in a GUI), then you can go ahead and set the value on the client, too, when the key is pressed, but expect it to be overridden by the 'real' value from the server. It's for convenience of display only.
how would i go about sending the code that the keys are pressed to the server, i wasnt aware that that was possible
edit: have you ever thought about using a proxy setup with a commonproxy, serverproxy, and clientproxy, where the serverproxy and clientproxy both extend the commonproxy? because, that way, it would eliminate the necessity of over riding your getEntityData and getThreadFromContext functions in the clientproxy.
@atijaf Aside from your design being questionable (iterating through all loaded TEs when a player joins the world? Certainly there is a better solution...), what version of Forge and Minecraft are you using?
I am using Version 1.8.8. And you're right that I should find a better solution. -- I think I'll save the list of the Te's I'm looking for to the world and then when loading the world, I'll just load from that.
Rollback Post to RevisionRollBack
I complicate easy problems, come begging for help, and leave with a simple solution.
I am using Version 1.8.8. And you're right that I should find a better solution. -- I think I'll save the list of the Te's I'm looking for to the world and then when loading the world, I'll just load from that.
Do you know that TileEntities already automatically send a packet to each client player when the TE loads for that player? You can already add extra information to this packet: in your TE, override #getDescriptionPacket (to add extra data) and #onDataPacket (to do stuff with that data).
E.g.
@Override
public Packet getDescriptionPacket() {
NBTTagCompound tag = new NBTTagCompound();
this.writeToNBT(tag);
return new S35PacketUpdateTileEntity(getPos(), 1, tag);
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) {
readFromNBT(packet.getNbtCompound());
}
There still remains one problem, though. Sending a packet to player.. Or to client, for that matter. Have you any idea why the crash is happening?
I'm aware of what "IndexOutOfBoundsException" is, but why am I getting that?
io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99) ~[MessageToMessageDecoder.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) [EmbeddedChannel.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:90) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:158) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:54) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(NetworkDispatcher.java:390) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:256) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:54) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:326) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:45) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:312) [LocalChannel$5.class:4.0.23.Final]
at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.class:4.0.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [SingleThreadEventExecutor$2.class:4.0.23.Final]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_66]
Caused by: java.lang.IndexOutOfBoundsException
at io.netty.buffer.EmptyByteBuf.readByte(EmptyByteBuf.java:440) ~[EmptyByteBuf.class:4.0.23.Final]
at net.minecraft.network.PacketBuffer.readByte(PacketBuffer.java:667) ~[PacketBuffer.class:?]
at net.minecraftforge.fml.common.network.ByteBufUtils.readVarInt(ByteBufUtils.java:46) ~[ByteBufUtils.class:?]
at EnergyTools.network.packet.client.SyncTeleporterContents.read(SyncTeleporterContents.java:25) ~[SyncTeleporterContents.class:?]
at EnergyTools.network.AbstractMessage.fromBytes(AbstractMessage.java:81) ~[AbstractMessage.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:17) ~[SimpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:7) ~[SimpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:81) ~[FMLIndexedMessageToMessageCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:21) ~[FMLIndexedMessageToMessageCodec.class:?]
at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) ~[MessageToMessageCodec$2.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[MessageToMessageDecoder.class:4.0.23.Final]
... 24 more
[04:46:42] [Netty Local Client IO #1/ERROR] [FML]: SimpleChannelHandlerWrapper exception
io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99) ~[MessageToMessageDecoder.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) [EmbeddedChannel.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:90) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:158) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:54) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(NetworkDispatcher.java:390) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:256) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:54) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:326) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:45) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:312) [LocalChannel$5.class:4.0.23.Final]
at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.class:4.0.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [SingleThreadEventExecutor$2.class:4.0.23.Final]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_66]
Caused by: java.lang.IndexOutOfBoundsException
at io.netty.buffer.EmptyByteBuf.readByte(EmptyByteBuf.java:440) ~[EmptyByteBuf.class:4.0.23.Final]
at net.minecraft.network.PacketBuffer.readByte(PacketBuffer.java:667) ~[PacketBuffer.class:?]
at net.minecraftforge.fml.common.network.ByteBufUtils.readVarInt(ByteBufUtils.java:46) ~[ByteBufUtils.class:?]
at EnergyTools.network.packet.client.SyncTeleporterContents.read(SyncTeleporterContents.java:25) ~[SyncTeleporterContents.class:?]
at EnergyTools.network.AbstractMessage.fromBytes(AbstractMessage.java:81) ~[AbstractMessage.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:17) ~[SimpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:7) ~[SimpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:81) ~[FMLIndexedMessageToMessageCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:21) ~[FMLIndexedMessageToMessageCodec.class:?]
at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) ~[MessageToMessageCodec$2.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[MessageToMessageDecoder.class:4.0.23.Final]
... 24 more
[04:46:42] [Netty Local Client IO #1/ERROR] [FML]: There was a critical exception handling a packet on channel et
io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99) ~[MessageToMessageDecoder.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) ~[DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:90) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:158) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:54) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(NetworkDispatcher.java:390) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:256) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:54) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:326) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:45) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:312) [LocalChannel$5.class:4.0.23.Final]
at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.class:4.0.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [SingleThreadEventExecutor$2.class:4.0.23.Final]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_66]
Caused by: java.lang.IndexOutOfBoundsException
at io.netty.buffer.EmptyByteBuf.readByte(EmptyByteBuf.java:440) ~[EmptyByteBuf.class:4.0.23.Final]
at net.minecraft.network.PacketBuffer.readByte(PacketBuffer.java:667) ~[PacketBuffer.class:?]
at net.minecraftforge.fml.common.network.ByteBufUtils.readVarInt(ByteBufUtils.java:46) ~[ByteBufUtils.class:?]
at EnergyTools.network.packet.client.SyncTeleporterContents.read(SyncTeleporterContents.java:25) ~[SyncTeleporterContents.class:?]
at EnergyTools.network.AbstractMessage.fromBytes(AbstractMessage.java:81) ~[AbstractMessage.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:17) ~[SimpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.decodeInto(SimpleIndexedCodec.java:7) ~[SimpleIndexedCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:81) ~[FMLIndexedMessageToMessageCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:21) ~[FMLIndexedMessageToMessageCodec.class:?]
at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) ~[MessageToMessageCodec$2.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[MessageToMessageDecoder.class:4.0.23.Final]
... 24 more
[04:46:42] [Server thread/INFO]: Player231 lost connection: TextComponent{text='Disconnected', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null, insertion=null}}
[04:46:42] [Server thread/INFO]: Player231 left the game
[04:46:42] [Server thread/INFO]: Stopping singleplayer server as player logged out
[04:46:42] [Server thread/INFO]: Stopping server
[04:46:42] [Server thread/INFO]: Saving players
[04:46:42] [Server thread/INFO]: Saving worlds
[04:46:42] [Server thread/INFO]: Saving chunks for level 'Copy of New World'/Overworld
[04:46:42] [Server thread/INFO]: Saving chunks for level 'Copy of New World'/Nether
[04:46:42] [Server thread/INFO]: Saving chunks for level 'Copy of New World'/The End
[04:46:42] [Server thread/INFO] [FML]: Unloading dimension 0
[04:46:42] [Server thread/INFO] [FML]: Unloading dimension -1
[04:46:42] [Server thread/INFO] [FML]: Unloading dimension 1
[04:46:42] [Server thread/INFO] [FML]: Applying holder lookups
[04:46:42] [Server thread/INFO] [FML]: Holder lookups applied
[/spoier]
Here are the classes related. Basically the same as before
I have a block that rarely ever spawns. Player's stats depend on how close they are to this block.
Now to get to the problem. There can be upwards to 100 of these blocks and the server will be calculating how close each and every single player is to the closest block. (So it has to go through all 100 to figure out which is closest. I haven't worked on improving how efficient it is yet, but I will, so lets ignore that part)
I would prefer the client player to determine how close they are, and then send a packet letting the server side know how close they are so that the server can calculate the stats that need to be changed for the player.
I'm working on a way to send the message to the server, I just don't know what to put in "onMessage."
I complicate easy problems, come begging for help, and leave with a simple solution.
@atijaf Why would you prefer the client player? That makes no sense - the server side player is equally if not more valid to use, as that has the player's 'real' position in the world. Simply calculate it directly - you shouldn't need any packets at all.
I had a feeling that calculating the closest block to each player would be a resource hog... I was also wanting to understand how to send instructions, as I have multiple uses for sending a packet with instructions.
I complicate easy problems, come begging for help, and leave with a simple solution.
It's only a resource hog if you design it that way, and if it is it will be so no matter which side you do it on. Whenever you have a design that is a resource hog, that's a big clue that you may want to re-think your approach. Sometimes it is the only way, but often you can find more optimal solutions, especially if you are willing to alter your design (e.g. only check for blocks within a certain radius of each player, rather than searching for all of them in the world [which is impossible, btw, unless you have a very small and fixed-size world]).
As for 'sending instructions' - what do you mean by that? Packets can send only bytes of information, so whatever you can store in bytes (e.g. integers, Strings, NBT, objects encoded into primitive types, etc.), you can send via packet. That is, you can only send information. What you do with that information is up to you, and you can do anything you want.
In other words, I think of the packet handler as containing all of the instructions, but it needs information from the packet in order to do anything meaningful. You don't 'send' instructions, you write instructions into your packet handler to process information it receives.
I am now on a new problem. I have a gui and am working to have a scrolling bar within it.
I override mouseClickMove from within GuiContainer so that when I move my mouse and left click, a variable changes. The only problem is that this method is a client side only method. (Or at least it doesn't update on the server)
So I need to send a packet to the server telling what row the player is on, but I'm unsure how to obtain the instance of the container i'm using. Here is all the relative code.
GuiModTileEntity
http://pastebin.com/tvqxYQdw
EDIT:
I messed with the code a little bit and it seems to be working. Would you mind letting me know if I did alright with it?
SyncGuiRow
http://pastebin.com/XRhrTGz7
I complicate easy problems, come begging for help, and leave with a simple solution.
I'm not sure what you're trying to do - what is this 'row' for? Is it for the scrollbar? If so, why do you need to send a packet - are you saving the player's position in the scrollbar for the next time they open the GUI? That's the only reason I can think of that you would send a packet for a scrollbar.
Please watch VSWE's Climbing the Interface Ladder tutorials. They will help you immensely in creating a dynamic GUI.
umm, not certain why this is happening, but I made a packet to send some booleans to my server, because the booleans are toggled by keybinds, spent a couple hours trying to figure out why the packet wasn't sending, then realized that i had accidentally set it to send it to the client. I switched it to send to server, and then started getting this error.
[21:44:25] [Netty Server IO #1/ERROR]: SimpleChannelHandlerWrapper exception
java.lang.ClassCastException: com.kookyboy9.wheeloftimemod.packets.SyncPlayerPropsMessage cannot be cast to com.kookyboy9.wheeloftimemod.packets.SyncPlayerPropsFromClient
at com.kookyboy9.wheeloftimemod.packets.SyncPlayerPropsFromClient$SyncPlayerPropsFromClientMessageHandler.handleServerMessage(SyncPlayerPropsFromClient.java:1) ~[SyncPlayerPropsFromClient$SyncPlayerPropsFromClientMessageHandler.class:?]
at com.kookyboy9.wheeloftimemod.packets.AbstractMessageHandler.onMessage(AbstractMessageHandler.java:62) ~[AbstractMessageHandler.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:37) ~[SimpleChannelHandlerWrapper.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:17) ~[SimpleChannelHandlerWrapper.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) ~[SimpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [MessageToMessageDecoder.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) [MessageToMessageCodec.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) [EmbeddedChannel.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:79) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:136) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:414) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [SimpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:409) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:237) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:50) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [SimpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:312) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:44) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel$6.run(LocalChannel.java:298) [LocalChannel$6.class:4.0.15.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354) [SingleThreadEventExecutor.class:4.0.15.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353) [NioEventLoop.class:4.0.15.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [SingleThreadEventExecutor$2.class:4.0.15.Final]
at java.lang.Thread.run(Thread.java:744) [?:1.7.0_51]
any idea whats going on?
edit:this happens after starting a world, just before it is possible to do anything, and just before the world generates in your client.
Each packet needs to be registered somewhere that is called on both client and server, and each packet class should use the same ID if registering it to be handled on both sides. Note that for the sake of brevity the example above does not use automated IDs or specify a real IMessageHandler.
my packets are called from my main mod class, and when i made the above modifications, they stopped crashing, but now for no apparent reason they only send once in a while.
here is the code in each of my classes, seperated by lines of /s
my code is here
can you tell me what i did wrong?
Well... lots of things :\
1. You copied the code from my IEEP tutorial, meaning you have some outdated stuff in there (e.g. saveProxyData, which is deprecated in favor of using PlayerEvent.Clone, and you didn't change the EXT_PROP_NAME string value to something unique). Part of this isn't your fault, since the tutorial has not been updated due to forum editor issues. I recommend you read the tutorial on Github via the link above - they don't have editor issues.
2. You are updating server-side data with data from the client. This is a VERY bad idea. Only the server should be sending updates.
3. #serversideNBTSave and #loadServerSide both seem like really bad ideas, both for reason #2 above, and the way you've written it you will have to change the methods any time you want to add or remove a variable. Why not either a. use the already-available save/load NBT methods, or b. create a class to encapsulate your specific data that you need to update frequently, and give that class save/load NBT methods? It could even just be the IMessage class itself that you pass to the method so you don't have to change the parameters all the time.
4. You don't need to register every method to be handled on both sides; only register it with the Side that it is going to be sent to. 99% of packets are sent to only one side or the other, not both.
5. Your KeepSynchronizedEvent code... no. Why are you sending updates to both sides every single tick? Don't send updates unless something has changed. Also see #2. What do you expect to happen when the server sends its version to the client, and the client sends its version to the server? If they have different data, they will just keep swapping back and forth between the two. See #2.
Send updates directly from a method in which something changes, preferably a message that sends only what needs to be sent (e.g. UpdateCastingMessage, or put all your booleans in an array and send the array index to set along with the value, then you can have a generalized message class). That's one of the main reasons for setter methods.
well, the answer to #2 is that i need to send keyinput to the server.
is there a better way to do this than sending a packet from the client?
Is that what all those boolean fields are for? Typically, you send 'key {code} was pressed' to the server, then the server decides what to do with it. E.g. 'key {fire} was pressed', so the server checks if the player can start using fire and, if so, sets the 'fire' boolean value and sends an update packet to the client saying 'fire is now true'.
So: client informs server of key press; server informs client of actual state.
If you're certain that 'fire' will be true after the key press is handled completely by the server, and / or you want to have immediate feedback to the client player (e.g. show which type is selected in a GUI), then you can go ahead and set the value on the client, too, when the key is pressed, but expect it to be overridden by the 'real' value from the server. It's for convenience of display only.
yeah, thats what the booleans were for.
how would i go about sending the code that the keys are pressed to the server, i wasnt aware that that was possible
edit: have you ever thought about using a proxy setup with a commonproxy, serverproxy, and clientproxy, where the serverproxy and clientproxy both extend the commonproxy? because, that way, it would eliminate the necessity of over riding your getEntityData and getThreadFromContext functions in the clientproxy.
Oh no! What did I do!
https://gyazo.com/5c2ef6c62d6e0a8d0ca506ced4f1e044
Happens on world load, I send a packet to the player loading the world about a certain tile entity. I notice while debugging, #process is never called
Here are my classes.
Packet Dispatcher:
http://pastebin.com/ExQQkkBd
EventHandler
http://pastebin.com/AatNkcXy -- Just the code that counts. If you need the rest of it, lemme know
SyncTeleporterTE
http://pastebin.com/2s9HDAvw
Main preInit
http://pastebin.com/V4pqkf3x
I complicate easy problems, come begging for help, and leave with a simple solution.
@atijaf Aside from your design being questionable (iterating through all loaded TEs when a player joins the world? Certainly there is a better solution...), what version of Forge and Minecraft are you using?
I am using Version 1.8.8. And you're right that I should find a better solution. -- I think I'll save the list of the Te's I'm looking for to the world and then when loading the world, I'll just load from that.
I complicate easy problems, come begging for help, and leave with a simple solution.
Do you know that TileEntities already automatically send a packet to each client player when the TE loads for that player? You can already add extra information to this packet: in your TE, override #getDescriptionPacket (to add extra data) and #onDataPacket (to do stuff with that data).
E.g.
oh...
THANKS! YOU'RE A LIFE SAVER SORRY FOR SMACKING YOUR FACE WITH SUCH QUESTION.
I complicate easy problems, come begging for help, and leave with a simple solution.
The simplest solution is almost always the right solution, but first you have to know about it
There still remains one problem, though. Sending a packet to player.. Or to client, for that matter. Have you any idea why the crash is happening?
I'm aware of what "IndexOutOfBoundsException" is, but why am I getting that?
[/spoier]
Here are the classes related. Basically the same as before
Packet Dispatcher
http://pastebin.com/ExQQkkBd
Abstract Message
http://pastebin.com/YUhRx2kK
SyncTeleporterTE
http://pastebin.com/2s9HDAvw -- new
Main class -- pre init and init + variables used
http://pastebin.com/V4pqkf3x
Where the packet is sent from
http://pastebin.com/1Nc3ra9F
Common Proxy
http://pastebin.com/24Rc06cz
Client Proxy
http://pastebin.com/RFPjvtJz
Thanks again
I complicate easy problems, come begging for help, and leave with a simple solution.