package mods.phlenum.cll.network; import io.netty.handler.codec.MessageToMessageCodec; import java.util.ArrayList; import java.util.List; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandler.Sharable; import mods.phlenum.cll.network.packets.CLLPacket; import mods.phlenum.cll.network.packets.CLLPacketLauncherProcess; import static mods.phlenum.cll.lib.Reference.*; import net.minecraft.client.Minecraft; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; /** * The Combustible Lemon Launcher mod * https://github.com/Phlenum/Combustible-Lemon-Launcher * http://minecraft.curseforge.com/mc-mods/62429-combustible-lemon-launcher * * Adapted from <a href='http://www.minecraftforge.net/wiki/Netty_Packet_Handling'>Minecraft Forge Wiki</a> * * @author Phil Julian * @date 06 Jan 2016 */ @Sharable public class CLLPacketHandler extends MessageToMessageCodec<FMLProxyPacket, CLLPacket> implements ChannelHandler { private static ArrayList<Class<? extends CLLPacket>> registeredPackets = new ArrayList<Class<? extends CLLPacket>>(); public static void registerPacket(Class<? extends CLLPacket> packetClass){ if(!registeredPackets.contains(packetClass)){ registeredPackets.add(packetClass); } } public static void registerPackets(){ registerPacket(CLLPacketLauncherProcess.class); } /* * Minecraft.getMinecraft().thePlayer returns EntityPlayerSP, so dedicated servers crash here. * This method will be client side only so the dedicated server doesn't throw a ClassNotFoundException. * Workaround... */ @SideOnly(Side.CLIENT) private static void handleClient(CLLPacket packet){ packet.handleClientSide(Minecraft.getMinecraft().player); } @Override protected void encode(ChannelHandlerContext ctx, CLLPacket msg, List<Object> out) throws Exception { Class<? extends CLLPacket> packetClass = msg.getClass(); if(registeredPackets.contains(packetClass)){ ByteBuf writeBuffer = Unpooled.buffer(); ByteBufOutputStream bbos = new ByteBufOutputStream(writeBuffer); writeBuffer.writeByte(registeredPackets.indexOf(packetClass)); msg.writeDataTo(bbos); FMLProxyPacket packet = new FMLProxyPacket(new PacketBuffer(writeBuffer.copy()), MOD_CHANNEL); bbos.close(); out.add(packet); } } @Override protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List<Object> out) throws Exception { ByteBuf packetPayload = msg.payload(); byte indexOfClass = packetPayload.readByte(); ByteBufInputStream bbis = new ByteBufInputStream(packetPayload.slice()); Class<? extends CLLPacket> packetClass = registeredPackets.get(indexOfClass); if(packetClass != null){ CLLPacket packetCLL = packetClass.newInstance(); packetCLL.readDataFrom(bbis); switch(FMLCommonHandler.instance().getEffectiveSide()){ case CLIENT: handleClient(packetCLL); break; case SERVER: packetCLL.handleServerSide(((NetHandlerPlayServer)ctx.channel().attr(NetworkRegistry.NET_HANDLER).get()).playerEntity); break; } bbis.close(); out.add(packetCLL); } } }