content: /*
   * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase
   * Copyright (C) 2023 FlorianMichael/EnZaXD and contributors
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package de.florianmichael.vialoadingbase.netty.handler;
  
  import com.viaversion.viaversion.api.connection.UserConnection;
  import com.viaversion.viaversion.exception.CancelCodecException;
  import com.viaversion.viaversion.exception.CancelEncoderException;
  import com.viaversion.viaversion.util.PipelineUtil;
  import io.netty.buffer.ByteBuf;
  import io.netty.channel.ChannelHandler;
  import io.netty.channel.ChannelHandlerContext;
  import io.netty.handler.codec.MessageToMessageEncoder;
  
  import java.util.List;
  
  @ChannelHandler.Sharable
  public class VLBViaEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
      private final UserConnection user;
  
      public VLBViaEncodeHandler(UserConnection user) {
          this.user = user;
      }
  
      @Override
      protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
          if (!user.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
          if (!user.shouldTransformPacket()) {
              out.add(bytebuf.retain());
              return;
          }
  
          ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
          try {
              user.transformOutgoing(transformedBuf, CancelEncoderException::generate);
  
              out.add(transformedBuf.retain());
          } finally {
              transformedBuf.release();
          }
      }
  
      @Override
      public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
          if (PipelineUtil.containsCause(cause, CancelCodecException.class)) return;
          super.exceptionCaught(ctx, cause);
      }
  }
  