PlanetTeamSpeak Posted April 14, 2019 Posted April 14, 2019 (edited) I am trying to create a way to extend reach, I've managed to get it to work, but I would like to use packets to make it work on both the server and the client and to transmit other data in the future; however, whenever I try to send a packet when a PlayerInteractEvent.LeftClickAir event is fired, it throws an exception. Edit: version is 1.12.2 Exception thrown: io.netty.handler.codec.EncoderException: java.lang.IndexOutOfBoundsException: readerIndex(0) + length(4) exceeds writerIndex(1): UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 1, cap: 256) at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:106) at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116) at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738) at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:801) at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814) at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794) at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:831) at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1032) at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:296) at net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToServer(SimpleNetworkWrapper.java:321) at com.ptsmods.morecommands.miscellaneous.ClientEventHandler.onPlayerLeftClickAir(ClientEventHandler.java:78) at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_16_ClientEventHandler_onPlayerLeftClickAir_LeftClickEmpty.invoke(.dynamic) at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182) at net.minecraftforge.common.ForgeHooks.onEmptyLeftClick(ForgeHooks.java:1135) at net.minecraft.client.Minecraft.clickMouse(Minecraft.java:1641) at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2375) at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2146) at net.minecraft.client.Minecraft.runTick(Minecraft.java:1934) at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1187) at net.minecraft.client.Minecraft.run(Minecraft.java:441) at net.minecraft.client.main.Main.main(Main.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:25) Caused by: java.lang.IndexOutOfBoundsException: readerIndex(0) + length(4) exceeds writerIndex(1): UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 1, cap: 256) at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1396) at io.netty.buffer.AbstractByteBuf.readInt(AbstractByteBuf.java:766) at net.minecraft.network.PacketBuffer.readInt(PacketBuffer.java:953) at com.ptsmods.morecommands.net.ClientLeftClickEventPacket.toBytes(ClientLeftClickEventPacket.java:59) at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:30) at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:26) at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.encode(FMLIndexedMessageToMessageCodec.java:81) at io.netty.handler.codec.MessageToMessageCodec$1.encode(MessageToMessageCodec.java:67) at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:88) ... 33 more PlayerInteractEvent.LeftClickEmpty listener (ignore first line of the method, that's of another feature): @SubscribeEvent public void onPlayerLeftClickAir(PlayerInteractEvent.LeftClickEmpty event) throws CommandException { Reference.powerToolCommand(event.getEntityPlayer(), event.getHand(), event, true); int blockReachDistance = Reference.getBlockReach(); Vec3d vec3d = event.getEntityPlayer().getPositionEyes(1F); Vec3d vec3d1 = event.getEntityPlayer().getLook(1F); Vec3d vec3d2 = vec3d.addVector(vec3d1.x * blockReachDistance, vec3d1.y * blockReachDistance, vec3d1.z * blockReachDistance); RayTraceResult result = event.getWorld().rayTraceBlocks(vec3d, vec3d2, false, false, true); BlockPos pos = result == null ? null : result.getBlockPos(); result = Reference.getObjectMouseOver(blockReachDistance, 1F) == null ? result : Reference.getObjectMouseOver(blockReachDistance, 1F); Reference.print(LogType.INFO, pos, event.isCanceled(), event.getEntityPlayer().capabilities.isCreativeMode, FMLCommonHandler.instance().getSide(), blockReachDistance); if (pos != null && !event.isCanceled() && event.getEntityPlayer().capabilities.isCreativeMode); Reference.netWrapper.sendToServer(new ClientLeftClickEventPacket(result, event.getEntityPlayer().dimension)); } Packet/message registering (called in preinit, netWrapper is an instance of SimpleNetworkWrapper): public static void loadPackets() { int i = 0; for (Class clazz : new Reflections("com.ptsmods.morecommands.net").getSubTypesOf(AbstractPacket.class)) { try { Reference.print(LogType.INFO, "Registering packet", clazz.getName(), "of handler class", clazz.getDeclaredMethod("getHandler").invoke(null).getClass().getName(), "with a discriminator of", i++ + "."); netWrapper.registerMessage((IMessageHandler) clazz.getDeclaredMethod("getHandler").invoke(null), clazz, i, clazz.getName().startsWith("Server") ? Side.CLIENT : Side.SERVER); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { e.printStackTrace(); } } } ClientLeftClickEventPacket.java: package com.ptsmods.morecommands.net; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.UUID; import com.google.gson.Gson; import com.ptsmods.morecommands.miscellaneous.Reference; import com.ptsmods.morecommands.miscellaneous.Reference.LogType; import io.netty.buffer.ByteBuf; import net.minecraft.server.MinecraftServer; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class ClientLeftClickEventPacket extends AbstractPacket { private static final IMessageHandler handler = new ClientLeftClickEventHandler(); private int jsonLength; private String jsonResult; private int dimension; public ClientLeftClickEventPacket() { } public ClientLeftClickEventPacket(RayTraceResult result, int dimension) { if (result != null) { Map<String, String> s = new HashMap(); s.put("subHit", "" + result.subHit); s.put("hitInfo", result.hitInfo == null ? "" : result.hitInfo.toString()); s.put("blockPos", result.getBlockPos() == null ? ";;" : result.getBlockPos().getX() + ";" + result.getBlockPos().getY() + ";" + result.getBlockPos().getZ()); s.put("type", result.typeOfHit == null ? "" : result.typeOfHit.name()); s.put("sideHit", result.sideHit == null ? "" : result.sideHit.name()); s.put("hitVec", result.hitVec == null ? ";;" : result.hitVec.x + ";" + result.hitVec.y + ";" + result.hitVec.z); s.put("entity", result.entityHit == null ? "" : result.entityHit.getUniqueID().toString()); this.dimension = dimension; Gson gson = new Gson(); jsonResult = gson.toJson(s); } } @Override public void fromBytes(ByteBuf buf) { buf.writeInt(jsonLength); buf.writeCharSequence(jsonResult, StandardCharsets.UTF_8); buf.writeInt(dimension); } @Override public void toBytes(ByteBuf buf) { jsonLength = buf.readInt(); jsonResult = buf.readCharSequence(jsonLength, StandardCharsets.UTF_8).toString(); dimension = buf.readInt(); } public static IMessageHandler<? extends AbstractPacket, ?> getHandler() { return handler; } public static class ClientLeftClickEventHandler implements IMessageHandler<ClientLeftClickEventPacket, IMessage> { @Override public IMessage onMessage(ClientLeftClickEventPacket message, MessageContext ctx) { Reference.print(LogType.INFO, "Received message ClientLeftClickEventPacket"); Map<String, String> s = new Gson().fromJson(message.jsonResult, Map.class); MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); Vec3d hitVec = new Vec3d(Double.parseDouble(s.get("hitVec").split(";")[0]), Double.parseDouble(s.get("hitVec").split(";")[1]), Double.parseDouble(s.get("hitVec").split(";")[2])); RayTraceResult result; if (s.get("entity").equals("")) { result = new RayTraceResult(RayTraceResult.Type.valueOf(s.get("type")), hitVec, EnumFacing.valueOf(s.get("sideHit")), new BlockPos(Double.parseDouble(s.get("blockPos").split(";")[0]), Double.parseDouble(s.get("blockPos").split(";")[1]), Double.parseDouble(s.get("blockPos").split(";")[2]))); server.getWorld(message.dimension).destroyBlock(result.getBlockPos(), false); } else { result = new RayTraceResult(server.getEntityFromUuid(UUID.fromString(s.get("entity"))), hitVec); result.entityHit.attackEntityFrom(DamageSource.GENERIC, 4); } return null; } } } AbstractPacket.java: package com.ptsmods.morecommands.net; import io.netty.buffer.ByteBuf; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; public abstract class AbstractPacket implements IMessage { @Override public abstract void fromBytes(ByteBuf buf); @Override public abstract void toBytes(ByteBuf buf); public static IMessageHandler<? extends AbstractPacket, ?> getHandler() { return null; } } And when sending a different packet, ServerBlockReachUpdate, from the server, the same exception is thrown. ServerBlockReachUpdate.java: package com.ptsmods.morecommands.net; import com.ptsmods.morecommands.miscellaneous.Reference; import com.ptsmods.morecommands.miscellaneous.Reference.LogType; import io.netty.buffer.ByteBuf; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class ServerBlockReachUpdatePacket extends AbstractPacket { public int blockReach; private static final IMessageHandler handler = new ServerBlockReachUpdateHandler(); public ServerBlockReachUpdatePacket(int blockReach) { this.blockReach = blockReach; } @Override public void fromBytes(ByteBuf buf) { Reference.print(LogType.INFO, buf.capacity()); buf.writeInt(blockReach); } @Override public void toBytes(ByteBuf buf) { blockReach = buf.readInt(); } public static IMessageHandler<? extends AbstractPacket, ?> getHandler() { return handler; } public static class ServerBlockReachUpdateHandler implements IMessageHandler<ServerBlockReachUpdatePacket, IMessage> { @Override public IMessage onMessage(ServerBlockReachUpdatePacket message, MessageContext ctx) { Reference.setBlockReach(message.blockReach); return null; } } } Edited April 14, 2019 by PlanetTeamSpeak Quote
V0idWa1k3r Posted April 14, 2019 Posted April 14, 2019 You are writing in the read function and reading in the write function. Quote @Override public void fromBytes(ByteBuf buf) { buf.writeInt(jsonLength); buf.writeCharSequence(jsonResult, StandardCharsets.UTF_8); buf.writeInt(dimension); } @Override public void toBytes(ByteBuf buf) { jsonLength = buf.readInt(); jsonResult = buf.readCharSequence(jsonLength, StandardCharsets.UTF_8).toString(); dimension = buf.readInt(); } Expand 1 Quote
PlanetTeamSpeak Posted April 14, 2019 Author Posted April 14, 2019 On 4/14/2019 at 5:39 PM, V0idWa1k3r said: You are writing in the read function and reading in the write function. Expand Omg wow, thanks for pointing that out. I cannot believe how obvious it was, but I totally overlooked it. Thank you! I'll try it asap and return if I have any problems. Quote
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.