@Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
        throws Exception {
      for (Entry<PacketListener, List<Method>> listener : OUT.entrySet()) {
        for (Method method : listener.getValue()) {

          PacketHandler ann = method.getAnnotation(PacketHandler.class);
          if (!ann.packet().getName().equals(msg.getClass().getSimpleName())) continue;
          PacketEvent evt = new PacketEvent(player, msg);
          method.setAccessible(true);
          method.invoke(listener.getKey(), evt);
          msg = evt.getPacket();
        }
      }

      if (msg != null) {
        super.write(ctx, msg, promise);
      }
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
      final Channel channel = ctx.channel();
      handleLoginStart(channel, msg);

      for (Entry<PacketListener, List<Method>> listener : IN.entrySet()) {
        for (Method method : listener.getValue()) {
          PacketHandler ann = method.getAnnotation(PacketHandler.class);
          if (!ann.packet().getName().equals(msg.getClass().getSimpleName())) continue;

          PacketEvent evt = new PacketEvent(player, msg);
          method.setAccessible(true);
          method.invoke(listener.getKey(), evt);
          method.setAccessible(false);
          msg = evt.getPacket();
        }
      }
      if (msg != null) {
        super.channelRead(ctx, msg);
      }
    }