package com.xcompwiz.lookingglass.network; import io.netty.buffer.ByteBuf; import java.util.HashMap; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.NetworkManager; import com.xcompwiz.lookingglass.log.LoggerUtils; import com.xcompwiz.lookingglass.network.packet.PacketHandlerBase; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.network.FMLEventChannel; import cpw.mods.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent; import cpw.mods.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class LookingGlassPacketManager { public static final String CHANNEL = "lookingglass"; public static FMLEventChannel bus; private static HashMap<Byte, PacketHandlerBase> packethandlers = new HashMap<Byte, PacketHandlerBase>(); private static HashMap<Class<? extends PacketHandlerBase>, Byte> idmap = new HashMap<Class<? extends PacketHandlerBase>, Byte>(); /** * Register a new packet handler to the manager. We use pre-defined packet ids to avoid mismatched packet ids across client-server communications. * @param handler The packet handler to register * @param id The id to which the handler should be bound */ public static void registerPacketHandler(PacketHandlerBase handler, byte id) { if (packethandlers.get(id) != null) { throw new RuntimeException("Multiple id registrations for packet type on " + CHANNEL + " channel"); } packethandlers.put(id, handler); idmap.put(handler.getClass(), id); } public static byte getId(PacketHandlerBase handler) { return getId(handler.getClass()); } public static byte getId(Class<? extends PacketHandlerBase> handlerclass) { if (!idmap.containsKey(handlerclass)) throw new RuntimeException("Attempted to get id for unregistered network message handler."); return idmap.get(handlerclass); } @SubscribeEvent @SideOnly(Side.CLIENT) public void onPacketData(ClientCustomPacketEvent event) { FMLProxyPacket pkt = event.packet; onPacketData(event.manager, pkt, Minecraft.getMinecraft().thePlayer); } @SubscribeEvent public void onPacketData(ServerCustomPacketEvent event) { FMLProxyPacket pkt = event.packet; onPacketData(event.manager, pkt, ((NetHandlerPlayServer) event.handler).playerEntity); } public void onPacketData(NetworkManager manager, FMLProxyPacket packet, EntityPlayer player) { try { if (packet == null || packet.payload() == null) { throw new RuntimeException("Empty packet sent to " + CHANNEL + " channel"); } ByteBuf data = packet.payload(); byte type = data.readByte(); try { PacketHandlerBase handler = packethandlers.get(type); if (handler == null) { throw new RuntimeException("Unrecognized packet sent to " + CHANNEL + " channel"); } handler.handle(data, player); } catch (Exception e) { LoggerUtils.warn("PacketHandler: Failed to handle packet type " + type); LoggerUtils.warn(e.toString()); e.printStackTrace(); } } catch (Exception e) { LoggerUtils.warn("PacketHandler: Failed to read packet"); LoggerUtils.warn(e.toString()); e.printStackTrace(); } } }