Posted May 16, 201510 yr I have recently started working with packets because our mods requires them. This is the code for the packet: import com.thedarkera.init.TDEBlocks; public class getManaPacket extends AbstractPacket { private int mana; public getManaPacket() { } public getManaPacket(int mana) { this.mana = mana; } public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { buffer.writeByte(mana); } public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { mana = buffer.readByte(); } public void handleClientSide(EntityPlayer player) { } public void handleServerSide(EntityPlayer player) { World world = Minecraft.getMinecraft().theWorld; int x = Minecraft.getMinecraft().objectMouseOver.blockX; int y = Minecraft.getMinecraft().objectMouseOver.blockY; int z = Minecraft.getMinecraft().objectMouseOver.blockZ; if (!(world.getBlock(x, y, z) == Blocks.air)) { world.setBlock(x, y, z+1, TDEBlocks.blockLog1, 0, 3); System.out.println(x + y + z); } } } This is the AbstractPackage class: package com.thedarkera.packet; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import net.minecraft.entity.player.EntityPlayer; public abstract class AbstractPacket { public abstract void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer); public abstract void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer); public abstract void handleClientSide(EntityPlayer player); public abstract void handleServerSide(EntityPlayer player); } And of course the PacketPipeline: package com.thedarkera.packet; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageCodec; import java.util.Collections; import java.util.Comparator; import java.util.EnumMap; import java.util.LinkedList; import java.util.List; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.INetHandler; import net.minecraft.network.NetHandlerPlayServer; import com.thedarkera.TheDarkEra; import com.thedarkera.utils.Ref; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.network.FMLEmbeddedChannel; import cpw.mods.fml.common.network.FMLOutboundHandler; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.relauncher.Side; @ChannelHandler.Sharable public class PacketPipeline extends MessageToMessageCodec<FMLProxyPacket, AbstractPacket> { private EnumMap<Side, FMLEmbeddedChannel> channels; private LinkedList<Class<? extends AbstractPacket>> packets = new LinkedList<Class<? extends AbstractPacket>>(); private boolean isPostInitialized = false; public boolean registerPacket(Class<? extends AbstractPacket> clazz) { if (this.packets.size() > 256) { TheDarkEra.logger.error("Maximum amount of packets reached!"); return false; } if (this.packets.contains(clazz)) { TheDarkEra.logger.error("This packet has already been registered!"); return false; } if (this.isPostInitialized == true) { TheDarkEra.logger.error("Packet registered too late!"); return false; } this.packets.add(clazz); return true; } public void initialize() { this.channels = NetworkRegistry.INSTANCE.newChannel(Ref.PACKET_CHANNEL_NAME, this); registerPackets(); } public void postInitialize(){ if(isPostInitialized) return; isPostInitialized = true; Collections.sort(this.packets, new Comparator<Class<? extends AbstractPacket>>(){ @Override public int compare(Class<? extends AbstractPacket> o1, Class<? extends AbstractPacket> o2){ int com = String.CASE_INSENSITIVE_ORDER.compare(o1.getCanonicalName(), o2.getCanonicalName()); if (com == 0) com = o1.getCanonicalName().compareTo(o2.getCanonicalName()); return com; } }); } public void registerPackets() { registerPacket(getManaPacket.class); } @Override protected void encode(ChannelHandlerContext ctx, AbstractPacket msg, List<Object> out) throws Exception { ByteBuf buffer = Unpooled.buffer(); Class<? extends AbstractPacket> clazz = msg.getClass(); if (!this.packets.contains(clazz)) { throw new NullPointerException("This packet has never been registered" + clazz.getCanonicalName()); } byte discriminator = (byte) this.packets.indexOf(clazz); buffer.writeByte(discriminator); msg.encodeInto(ctx, buffer); FMLProxyPacket proxyPacket = new FMLProxyPacket(buffer.copy(), ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get()); out.add(proxyPacket); } @Override protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List<Object> out) throws Exception { ByteBuf payload = msg.payload(); byte discriminator = payload.readByte(); Class<? extends AbstractPacket> clazz = this.packets.get(discriminator); if (clazz == null) { throw new NullPointerException("This packet has never been registered" + clazz.getCanonicalName()); } AbstractPacket abstractPacket = clazz.newInstance(); abstractPacket.decodeInto(ctx, payload.slice()); EntityPlayer player; switch (FMLCommonHandler.instance().getEffectiveSide()) { case CLIENT: player = Minecraft.getMinecraft().thePlayer; abstractPacket.handleClientSide(player); break; case SERVER: INetHandler iNetHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(); player = ((NetHandlerPlayServer) iNetHandler).playerEntity; abstractPacket.handleServerSide(player); break; default: } out.add(abstractPacket); } public void sendToServer(AbstractPacket message){ this.channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER); this.channels.get(Side.CLIENT).writeAndFlush(message); } } As you can see I'm trying to use setBlock at the coordinates the player is looking at. Problem is that it's only working client side and not server side. I haven't been able to find an answer to this yet, can anyone explain what i should use to set a block server side?
May 16, 201510 yr First, one word: SimpleNetworkWrapper http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-2-customizing-packet-handling-with Short and tight: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html Second: You can't use Minecraft.class on server logical side - never ever, that class is client only, and will crash on dedicated server. You either have to raytrace on client and send coordinates to server or copy client classes to your mod and use them on server (I am not sure if rayTrace exists on server, check it 1st). 1.7.10 is no longer supported by forge, you are on your own.
May 16, 201510 yr Author Thank you for explaining why i shouldn't use Minecraft.class. I managed to get the world from the server which fixed the setBlock problem. Code now: public void handleServerSide(EntityPlayer player) { EntityPlayerMP thePlayer = (EntityPlayerMP) player; World world = thePlayer.worldObj; int x = player.rayTrace(5, 1.0f).blockX; int y = player.rayTrace(5, 1.0f).blockY; int z = player.rayTrace(5, 1.0f).blockZ; // if (!(world.getBlock(x, y, z) == Blocks.air)) { world.setBlock(x, y, z, TDEBlocks.blockLog1, 0, 3); System.out.println(x + "_" + y + "_" + z); // } } As you can see i used the default reach distance (5) but it's not giving the same results as Minecraft.getMinecraft().objectMouseOver. I'm also not sure what the second argument for rayTrace should be. Looking at the code doesn't help much.
May 16, 201510 yr Author I found a way to do it. I send the client's objectMouseOver coordinates to the server using a packet. The packet then acceses it to set the block. Thanks for the help.
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.