ReflectiveChannelFactory class

Пакет: com.hypixel.hytale.server.core.io.netty

Файл: com/hypixel/hytale/server/core/io/netty/NettyUtil.java

implements: ChannelFactory<T>

Поля (1)

МодификаторыТипИмя
private final SocketProtocolFamily family

Методы (3)

МодификаторыВозвратСигнатура
public String getSimpleNamepublic String getSimpleName()
public T newChannelpublic T newChannel()
public String toStringpublic String toString()

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.io.netty;

class="kw">import com.google.common.flogger.LazyArgs;
class="kw">import com.hypixel.hytale.common.util.FormatUtil;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.logger.backend.HytaleLoggerBackend;
class="kw">import com.hypixel.hytale.protocol.FormattedMessage;
class="kw">import com.hypixel.hytale.protocol.NetworkChannel;
class="kw">import com.hypixel.hytale.protocol.ToClientPacket;
class="kw">import com.hypixel.hytale.protocol.io.ChannelConnection;
class="kw">import com.hypixel.hytale.protocol.io.ConnectionHandler;
class="kw">import com.hypixel.hytale.protocol.io.ConnectionOrigin;
class="kw">import com.hypixel.hytale.protocol.io.PacketStatsRecorder;
class="kw">import com.hypixel.hytale.protocol.io.ServerListener;
class="kw">import com.hypixel.hytale.protocol.io.netty.PacketDecoder;
class="kw">import com.hypixel.hytale.protocol.io.netty.PacketEncoder;
class="kw">import com.hypixel.hytale.protocol.io.netty.ProtocolUtil;
class="kw">import com.hypixel.hytale.protocol.packets.connection.DisconnectType;
class="kw">import com.hypixel.hytale.protocol.packets.connection.QuicApplicationErrorCode;
class="kw">import com.hypixel.hytale.protocol.packets.connection.ServerDisconnect;
class="kw">import com.hypixel.hytale.server.core.io.PacketHandler;
class="kw">import com.hypixel.hytale.server.core.io.transport.QUICTransport;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.util.concurrent.ThreadUtil;
class="kw">import io.netty.buffer.ByteBuf;
class="kw">import io.netty.buffer.Unpooled;
class="kw">import io.netty.channel.Channel;
class="kw">import io.netty.channel.ChannelException;
class="kw">import io.netty.channel.ChannelFactory;
class="kw">import io.netty.channel.ChannelFuture;
class="kw">import io.netty.channel.ChannelFutureListener;
class="kw">import io.netty.channel.ChannelHandler;
class="kw">import io.netty.channel.ChannelInitializer;
class="kw">import io.netty.channel.EventLoopGroup;
class="kw">import io.netty.channel.ServerChannel;
class="kw">import io.netty.channel.epoll.Epoll;
class="kw">import io.netty.channel.epoll.EpollDatagramChannel;
class="kw">import io.netty.channel.epoll.EpollEventLoopGroup;
class="kw">import io.netty.channel.epoll.EpollServerSocketChannel;
class="kw">import io.netty.channel.kqueue.KQueue;
class="kw">import io.netty.channel.kqueue.KQueueDatagramChannel;
class="kw">import io.netty.channel.kqueue.KQueueEventLoopGroup;
class="kw">import io.netty.channel.kqueue.KQueueServerSocketChannel;
class="kw">import io.netty.channel.nio.NioEventLoopGroup;
class="kw">import io.netty.channel.socket.DatagramChannel;
class="kw">import io.netty.channel.socket.SocketProtocolFamily;
class="kw">import io.netty.channel.socket.nio.NioDatagramChannel;
class="kw">import io.netty.channel.socket.nio.NioServerSocketChannel;
class="kw">import io.netty.handler.codec.quic.QuicChannel;
class="kw">import io.netty.handler.codec.quic.QuicStreamChannel;
class="kw">import io.netty.handler.codec.quic.QuicStreamPriority;
class="kw">import io.netty.handler.codec.quic.QuicStreamType;
class="kw">import io.netty.handler.codec.quic.QuicTransportError;
class="kw">import io.netty.handler.logging.LogLevel;
class="kw">import io.netty.handler.logging.LoggingHandler;
class="kw">import io.netty.util.AttributeKey;
class="kw">import io.netty.util.internal.ObjectUtil;
class="kw">import io.netty.util.internal.StringUtil;
class="kw">import io.netty.util.internal.SystemPropertyUtil;
class="kw">import java.lang.foreign.MemorySegment;
class="kw">import java.lang.reflect.Constructor;
class="kw">import java.net.SocketAddress;
class="kw">import java.security.cert.X509Certificate;
class="kw">import java.time.Duration;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.Future;
class="kw">import java.util.concurrent.ScheduledFuture;
class="kw">import java.util.concurrent.ThreadFactory;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.function.BiConsumer;
class="kw">import java.util.function.BooleanSupplier;
class="kw">import java.util.function.Function;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class NettyUtil {
   class="kw">public class="kw">static class="kw">final HytaleLogger CONNECTION_EXCEPTION_LOGGER = HytaleLogger.get("ConnectionExceptionLogging");
   class="kw">public class="kw">static class="kw">final HytaleLogger PACKET_LOGGER = HytaleLogger.get("PacketLogging");
   class="kw">public class="kw">static class="kw">final String PACKET_DECODER = "packetDecoder";
   class="kw">public class="kw">static class="kw">final String PACKET_ARRAY_ENCODER = "packetArrayEncoder";
   class="kw">public class="kw">static class="kw">final PacketArrayEncoder PACKET_ARRAY_ENCODER_INSTANCE = new PacketArrayEncoder();
   class="kw">public class="kw">static class="kw">final String PACKET_ENCODER = "packetEncoder";
   class="kw">public class="kw">static class="kw">final String LOGGER_KEY = "logger";
   class="kw">public class="kw">static class="kw">final LoggingHandler LOGGER = new LoggingHandler("PacketLogging", LogLevel.INFO);
   class="kw">public class="kw">static class="kw">final String HANDLER = "handler";
   class="kw">public class="kw">static class="kw">final String RATE_LIMIT = "rateLimit";
   class="kw">private class="kw">static class="kw">final int MAX_CLOSE_REASON_BYTES = 1000;
   class="kw">public class="kw">static class="kw">final ChannelFutureListener CLOSE_ON_COMPLETE = var0x -> closeApplicationConnection(var0x.channel());

   class="kw">public NettyUtil() {
   }

   class="kw">public class="kw">static void init() {
   }

   class="kw">public class="kw">static void closeConnection(@Nonnull Channel var0) {
      int var1 = (int)QuicTransportError.PROTOCOL_VIOLATION.code();
      if (var0 class="kw">instanceof QuicChannel var2) {
         var2.close(false, var1, Unpooled.EMPTY_BUFFER);
      } else if (var0.parent() class="kw">instanceof QuicChannel var3) {
         var3.close(false, var1, Unpooled.EMPTY_BUFFER);
      } else {
         var0.close();
      }
   }

   class="kw">public class="kw">static void closeApplicationConnection(@Nonnull Channel var0) {
      closeApplicationConnection(var0, QuicApplicationErrorCode.NoError);
   }

   class="kw">public class="kw">static void closeApplicationConnection(@Nonnull Channel var0, @Nonnull QuicApplicationErrorCode var1) {
      if (var0 class="kw">instanceof QuicChannel var2) {
         var2.close(true, var1.ordinal(), Unpooled.EMPTY_BUFFER);
      } else if (var0.parent() class="kw">instanceof QuicChannel var3) {
         var3.close(true, var1.ordinal(), Unpooled.EMPTY_BUFFER);
      } else {
         var0.close();
      }
   }

   class="kw">public class="kw">static void closeApplicationConnection(@Nonnull Channel var0, @Nonnull QuicApplicationErrorCode var1, @Nonnull FormattedMessage var2) {
      int var3 = var2.computeSize();
      if (var3 > 1000) {
         closeApplicationConnection(var0, var1);
      } else {
         byte[] var4 = new byte[var3];

         try {
            var2.serialize(MemorySegment.ofArray(var4), 0);
         } catch (Throwable var9) {
            closeApplicationConnection(var0, var1);
            throw var9;
         }

         ByteBuf var5 = Unpooled.wrappedBuffer(var4);
         if (var0 class="kw">instanceof QuicChannel var6) {
            var6.close(true, var1.ordinal(), var5);
         } else if (var0.parent() class="kw">instanceof QuicChannel var7) {
            var7.close(true, var1.ordinal(), var5);
         } else {
            var5.release();
            var0.close();
         }
      }
   }

   class="kw">private class="kw">static void injectLogger(@Nonnull Channel var0) {
      if (var0.pipeline().get("logger") == null) {
         var0.pipeline().addAfter("packetArrayEncoder", "logger", LOGGER);
      }
   }

   class="kw">private class="kw">static void uninjectLogger(@Nonnull Channel var0) {
      var0.pipeline().remove("logger");
   }

   class="kw">private class="kw">static void setChannelHandler(@Nonnull Channel var0, @Nonnull PacketHandler var1) {
      PlayerChannelHandler var2 = new PlayerChannelHandler(var1);
      PacketHandler var3 = null;
      ChannelHandler var4 = var0.pipeline().get("handler");
      if (var4 != null) {
         var0.pipeline().replace("handler", "handler", var2);
         if (var4 class="kw">instanceof PlayerChannelHandler var5) {
            var3 = var5.getHandler();
            var3.unregistered(var1);
         }
      } else {
         var0.pipeline().addLast("handler", var2);
      }

      if (var0 class="kw">instanceof QuicStreamChannel var6) {
         var6.parent().attr(HytaleChannelInitializer.GAME_PACKET_HANDLER_ATTR).set(var1);
      }

      var1.registered(var3);
   }

   @Nonnull
   class="kw">private class="kw">static CompletableFuture<Void> createStream(
      @Nonnull QuicChannel var0,
      @Nonnull QuicStreamType var1,
      @Nonnull NetworkChannel var2,
      @Nullable QuicStreamPriority var3,
      @Nonnull PacketHandler var4,
      @Nonnull BiConsumer<NetworkChannel, ChannelConnection> var5
   ) {
      CompletableFuture var6 = new CompletableFuture<>();
      var0.createStream(var1, new ChannelInitializer<Channel>() {
         class="kw">protected void initChannel(@Nonnull Channel var1) {
            var1.pipeline().addLast("packetDecoder", new PacketDecoder());
            var1.pipeline().addLast("packetEncoder", new PacketEncoder());
            var1.pipeline().addLast("packetArrayEncoder", NettyUtil.PACKET_ARRAY_ENCODER_INSTANCE);
         }
      }).addListener(var5x -> {
         if (!var5x.isSuccess()) {
            var6.completeExceptionally(var5x.cause());
         } else {
            QuicStreamChannel var6 = (QuicStreamChannel)var5x.getNow();
            var6.attr(ProtocolUtil.STREAM_CHANNEL_KEY).set(var2);
            if (var3 != null) {
               var6.updatePriority(var3);
            }

            setChannelHandler(var6, var4);
            NettyUtil.NettyChannelConnection var7 = new NettyUtil.NettyChannelConnection(var6);
            var5.accept(var2, var7);
            var6.complete(null);
         }
      });
      class="kw">return var6;
   }

   @Nonnull
   class="kw">public class="kw">static EventLoopGroup getEventLoopGroup(String var0) {
      class="kw">return getEventLoopGroup(0, var0);
   }

   @Nonnull
   class="kw">public class="kw">static EventLoopGroup getEventLoopGroup(int var0, String var1) {
      if (var0 == 0) {
         var0 = Math.max(1, SystemPropertyUtil.getInt("server.io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));
      }

      ThreadFactory var2 = ThreadUtil.daemonCounted(var1 + " - %d");
      if (Epoll.isAvailable()) {
         class="kw">return new EpollEventLoopGroup(var0, var2);
      } else {
         class="kw">return (EventLoopGroup)(KQueue.isAvailable() ? new KQueueEventLoopGroup(var0, var2) : new NioEventLoopGroup(var0, var2));
      }
   }

   @Nonnull
   class="kw">public class="kw">static Class<? class="kw">extends ServerChannel> getServerChannel() {
      if (Epoll.isAvailable()) {
         class="kw">return EpollServerSocketChannel.class;
      } else {
         class="kw">return KQueue.isAvailable() ? KQueueServerSocketChannel.class : NioServerSocketChannel.class;
      }
   }

   @Nonnull
   class="kw">public class="kw">static NettyUtil.ReflectiveChannelFactory<? class="kw">extends DatagramChannel> getDatagramChannelFactory(SocketProtocolFamily var0) {
      if (Epoll.isAvailable()) {
         class="kw">return new NettyUtil.ReflectiveChannelFactory(EpollDatagramChannel.class, var0);
      } else {
         class="kw">return KQueue.isAvailable()
            ? new NettyUtil.ReflectiveChannelFactory(KQueueDatagramChannel.class, var0)
            : new NettyUtil.ReflectiveChannelFactory(NioDatagramChannel.class, var0);
      }
   }

   class="kw">public class="kw">static String formatRemoteAddress(Channel var0) {
      if (var0 class="kw">instanceof QuicChannel var1) {
         class="kw">return var1.remoteAddress() + " (" + var1.remoteSocketAddress() + ")";
      } else {
         class="kw">return var0 class="kw">instanceof QuicStreamChannel var2
            ? var2.parent().localAddress() + " (" + var2.parent().remoteSocketAddress() + ", streamId=" + var2.remoteAddress().streamId() + ")"
            : var0.remoteAddress().toString();
      }
   }

   class="kw">public class="kw">static String formatLocalAddress(Channel var0) {
      if (var0 class="kw">instanceof QuicChannel var1) {
         class="kw">return var1.localAddress() + " (" + var1.localSocketAddress() + ")";
      } else {
         class="kw">return var0 class="kw">instanceof QuicStreamChannel var2
            ? var2.parent().localAddress() + " (" + var2.parent().localSocketAddress() + ", streamId=" + var2.localAddress().streamId() + ")"
            : var0.localAddress().toString();
      }
   }

   @Nullable
   class="kw">public class="kw">static SocketAddress getRemoteSocketAddress(Channel var0) {
      if (var0 class="kw">instanceof QuicChannel var1) {
         class="kw">return var1.remoteSocketAddress();
      } else {
         class="kw">return var0 class="kw">instanceof QuicStreamChannel var2 ? var2.parent().remoteSocketAddress() : var0.remoteAddress();
      }
   }

   class="kw">public class="kw">static boolean isFromSameOrigin(Channel var0, Channel var1) {
      class="kw">return ConnectionOrigin.isFromSameOrigin(getRemoteSocketAddress(var0), getRemoteSocketAddress(var1));
   }

   @Nonnull
   class="kw">public class="kw">static <T> CompletableFuture<T> wrapChannelFuture(@Nonnull ChannelFuture var0, @Nonnull Function<ChannelFuture, T> var1) {
      CompletableFuture var2 = new CompletableFuture<>();
      var0.addListener(var3 -> {
         if (var3.isSuccess()) {
            var2.complete(var1.apply(var0));
         } else {
            var2.completeExceptionally(var3.cause());
         }
      });
      class="kw">return var2;
   }

   class="kw">static {
      HytaleLoggerBackend var0 = HytaleLoggerBackend.getLogger(PACKET_LOGGER.getName());
      var0.setOnLevelChange((var0x, var1) -> {
         Universe var2 = Universe.get();
         if (var2 != null) {
            if (var1 == Level.OFF) {
               for (PlayerRef var4 : var2.getPlayers()) {
                  if (var4.getPacketHandler().getChannel() class="kw">instanceof NettyUtil.NettyChannelConnection(Channel var7)) {
                     uninjectLogger(var7);
                  }
               }
            } else {
               for (PlayerRef var12 : var2.getPlayers()) {
                  if (var12.getPacketHandler().getChannel() class="kw">instanceof NettyUtil.NettyChannelConnection(Channel var15)) {
                     injectLogger(var15);
                  }
               }
            }
         }
      });
      PACKET_LOGGER.setLevel(Level.OFF);
      var0.loadLogLevel();
      CONNECTION_EXCEPTION_LOGGER.setLevel(Level.ALL);
   }

   class="kw">public record NettyChannelConnection(Channel channel) class="kw">implements ChannelConnection {
      class="kw">private class="kw">static class="kw">final HytaleLogger LOGIN_TIMING_LOGGER = HytaleLogger.get("LoginTiming");
      class="kw">private class="kw">static class="kw">final AttributeKey<ScheduledFuture<?>> STAGE_TIMEOUT_KEY = AttributeKey.newInstance("STAGE_TIMEOUT");
      class="kw">private class="kw">static class="kw">final AttributeKey<Long> LOGIN_START_KEY = AttributeKey.newInstance("LOGIN_START");

      class="kw">public NettyChannelConnection {
      }

      @Override
      class="kw">public void flush() {
         this.channel.flush();
      }

      @Override
      class="kw">public void write(ToClientPacket var1) {
         this.channel.write(var1, this.channel.voidPromise());
      }

      @Override
      class="kw">public void writeAndFlush(ToClientPacket var1) {
         this.channel.writeAndFlush(var1, this.channel.voidPromise());
      }

      @Override
      class="kw">public void write(ToClientPacket[] var1) {
         this.channel.write(var1, this.channel.voidPromise());
      }

      @Override
      class="kw">public void writeAndFlush(ToClientPacket[] var1) {
         this.channel.writeAndFlush(var1, this.channel.voidPromise());
      }

      @Override
      class="kw">public boolean isActive() {
         class="kw">return this.channel.isActive();
      }

      @Override
      class="kw">public boolean isWritable() {
         class="kw">return this.channel.isWritable();
      }

      @Override
      class="kw">public SocketAddress remoteAddress() {
         SocketAddress var1;
         if (this.channel class="kw">instanceof QuicStreamChannel var2) {
            var1 = var2.parent().remoteSocketAddress();
         } else {
            var1 = this.channel.remoteAddress();
         }

         class="kw">return var1;
      }

      @Override
      class="kw">public String formatRemoteAddress() {
         class="kw">return NettyUtil.formatRemoteAddress(this.channel);
      }

      @Override
      class="kw">public void disconnect(@Nonnull FormattedMessage var1) {
         this.channel
            .writeAndFlush(new ServerDisconnect(var1, DisconnectType.Disconnect))
            .addListener((ChannelFutureListener)var2 -> NettyUtil.closeApplicationConnection(this.channel, QuicApplicationErrorCode.NoError, var1));
      }

      @Nullable
      @Override
      class="kw">public PacketStatsRecorder getPacketStatsRecorder() {
         class="kw">return (PacketStatsRecorder)this.channel.attr(PacketStatsRecorder.CHANNEL_KEY).get();
      }

      @Nullable
      @Override
      class="kw">public String getSniHostname() {
         class="kw">return this.channel class="kw">instanceof QuicStreamChannel var1 ? (String)var1.parent().attr(QUICTransport.SNI_HOSTNAME_ATTR).get() : null;
      }

      @Override
      class="kw">public boolean isFromSameOrigin(ChannelConnection var1) {
         class="kw">return var1 class="kw">instanceof NettyUtil.NettyChannelConnection var2 ? NettyUtil.isFromSameOrigin(this.channel, var2.channel) : false;
      }

      @Override
      class="kw">public void execute(Runnable var1) {
         this.channel.eventLoop().execute(var1);
      }

      @Nonnull
      @Override
      class="kw">public CompletableFuture<Void> setupAuxiliaryChannels(@Nonnull ConnectionHandler var1, @Nonnull BiConsumer<NetworkChannel, ChannelConnection> var2) {
         if (this.channel class="kw">instanceof QuicStreamChannel var3) {
            QuicChannel var8 = var3.parent();
            var8.attr(ProtocolUtil.STREAM_CHANNEL_KEY).set(NetworkChannel.Default);
            var3.updatePriority(PacketHandler.DEFAULT_STREAM_PRIORITIES.get(NetworkChannel.Default));
            PacketHandler var5 = (PacketHandler)var1;
            CompletableFuture var6 = NettyUtil.createStream(
               var8, QuicStreamType.UNIDIRECTIONAL, NetworkChannel.Chunks, PacketHandler.DEFAULT_STREAM_PRIORITIES.get(NetworkChannel.Chunks), var5, var2
            );
            CompletableFuture var7 = NettyUtil.createStream(
               var8, QuicStreamType.UNIDIRECTIONAL, NetworkChannel.WorldMap, PacketHandler.DEFAULT_STREAM_PRIORITIES.get(NetworkChannel.WorldMap), var5, var2
            );
            class="kw">return CompletableFuture.allOf(var6, var7);
         } else {
            var2.accept(NetworkChannel.WorldMap, this);
            var2.accept(NetworkChannel.Chunks, this);
            class="kw">return CompletableFuture.completedFuture(null);
         }
      }

      @Override
      class="kw">public void setChannelHandler(@Nonnull ConnectionHandler var1) {
         NettyUtil.setChannelHandler(this.channel, (PacketHandler)var1);
      }

      @Override
      class="kw">public X509Certificate getClientCertificate() {
         class="kw">return (X509Certificate)this.channel.attr(QUICTransport.CLIENT_CERTIFICATE_ATTR).get();
      }

      @Override
      class="kw">public void updateStreamPriority(int var1, boolean var2) {
         if (this.channel class="kw">instanceof QuicStreamChannel var3) {
            var3.updatePriority(new QuicStreamPriority(var1, var2));
         }
      }

      @Override
      class="kw">public void initTimeoutContext(@Nonnull String var1, @Nonnull String var2) {
         NettyUtil.TimeoutContext.init(this.channel, var1, var2);
      }

      @Override
      class="kw">public void updateTimeoutContext(@Nonnull String var1, @Nonnull String var2) {
         NettyUtil.TimeoutContext.update(this.channel, var1, var2);
      }

      @Override
      class="kw">public void updateTimeoutContext(@Nonnull String var1) {
         NettyUtil.TimeoutContext.update(this.channel, var1);
      }

      @Override
      class="kw">public void setPacketTimeout(@Nonnull Duration var1) {
         this.channel.attr(ProtocolUtil.PACKET_TIMEOUT_KEY).set(var1);
      }

      @Override
      class="kw">public void clearPacketTimeout() {
         this.channel.attr(ProtocolUtil.PACKET_TIMEOUT_KEY).set(null);
      }

      @Override
      class="kw">public void setStageTimeout(@Nonnull String var1, @Nonnull Duration var2, @Nonnull BooleanSupplier var3, @Nonnull Runnable var4) {
         ScheduledFuture var5 = (ScheduledFuture<?>)this.channel.attr(STAGE_TIMEOUT_KEY).get();
         if (var5 != null) {
            var5.cancel(false);
         }

         this.logConnectionTimings("Entering stage '" + var1 + "'", Level.FINEST);
         long var6 = var2.toMillis();
         io.netty.util.concurrent.ScheduledFuture var8 = this.channel
            .eventLoop()
            .schedule(
               () -> {
                  if (this.channel.isOpen()) {
                     if (!var3.getAsBoolean()) {
                        NettyUtil.TimeoutContext var4 = (NettyUtil.TimeoutContext)this.channel.attr(NettyUtil.TimeoutContext.KEY).get();
                        String var5 = var4 != null ? FormatUtil.nanosToString(System.nanoTime() - var4.connectionStartNs()) : "unknown";
                        HytaleLogger.getLogger()
                           .at(Level.WARNING)
                           .log("Stage timeout for %s at stage '%s' after %s connected", var4 != null ? var4.playerIdentifier() : "unknown", var1, var5);
                        var4.run();
                     }
                  }
               },
               var6,
               TimeUnit.MILLISECONDS
            );
         this.channel.attr(STAGE_TIMEOUT_KEY).set(var8);
      }

      @Override
      class="kw">public void clearStageTimeout() {
         ScheduledFuture var1 = (ScheduledFuture<?>)this.channel.attr(STAGE_TIMEOUT_KEY).get();
         if (var1 != null) {
            var1.cancel(false);
         }
      }

      @Override
      class="kw">public void logConnectionTimings(@Nonnull String var1, @Nonnull Level var2) {
         long var3 = System.nanoTime();
         NettyUtil.TimeoutContext var5 = (NettyUtil.TimeoutContext)this.channel.attr(NettyUtil.TimeoutContext.KEY).get();
         String var6 = var5 != null ? var5.playerIdentifier() : NettyUtil.formatRemoteAddress(this.channel);
         Long var7 = (Long)this.channel.attr(LOGIN_START_KEY).getAndSet(var3);
         if (var7 == null) {
            LOGIN_TIMING_LOGGER.at(var2).log("[%s] %s", var6, var1);
         } else {
            long var8 = var3 - var7;
            LOGIN_TIMING_LOGGER.at(var2).log("[%s] %s took %s", var6, var1, LazyArgs.lazy(() -> FormatUtil.nanosToString(var8)));
         }
      }

      @Override
      class="kw">public void closeConnection() {
         this.close(false, 0);
      }

      @Override
      class="kw">public void closeApplicationConnection() {
         this.close(true, QuicApplicationErrorCode.NoError.ordinal());
      }

      @Override
      class="kw">public void closeApplicationConnection(@Nonnull QuicApplicationErrorCode var1) {
         this.close(true, var1.ordinal());
      }

      @Override
      class="kw">public void closeApplicationConnection(@Nonnull QuicApplicationErrorCode var1, @Nonnull FormattedMessage var2) {
         NettyUtil.closeApplicationConnection(this.channel, var1, var2);
      }

      class="kw">private void close(boolean var1, int var2) {
         if (this.channel class="kw">instanceof QuicChannel var3) {
            var3.close(var1, var2, Unpooled.EMPTY_BUFFER);
         } else if (this.channel.parent() class="kw">instanceof QuicChannel var4) {
            var4.close(var1, var2, Unpooled.EMPTY_BUFFER);
         } else {
            this.channel.close();
         }
      }

      @Override
      class="kw">public boolean equals(Object var1) {
         if (this == var1) {
            class="kw">return true;
         } else {
            class="kw">return var1 class="kw">instanceof NettyUtil.NettyChannelConnection(Channel var3) ? this.channel.equals(var3) : false;
         }
      }

      @Override
      class="kw">public int hashCode() {
         class="kw">return this.channel.hashCode();
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return this.channel.toString();
      }
   }

   class="kw">public record NettyChannelServerListener(Channel channel) class="kw">implements ServerListener {
      class="kw">public NettyChannelServerListener {
      }

      @Override
      class="kw">public Future<Void> close() {
         class="kw">return NettyUtil.wrapChannelFuture(this.channel.close(), var0 -> null);
      }

      @Override
      class="kw">public SocketAddress localAddress() {
         class="kw">return this.channel.localAddress();
      }
   }

   class="kw">public class="kw">static class ReflectiveChannelFactory<T class="kw">extends Channel> class="kw">implements ChannelFactory<T> {
      @Nonnull
      class="kw">private class="kw">final Constructor<? class="kw">extends T> constructor;
      class="kw">private class="kw">final SocketProtocolFamily family;

      class="kw">public ReflectiveChannelFactory(@Nonnull Class<? class="kw">extends T> var1, SocketProtocolFamily var2) {
         ObjectUtil.checkNotNull(var1, "clazz");

         try {
            this.constructor = var1.getConstructor(SocketProtocolFamily.class);
            this.family = var2;
         } catch (NoSuchMethodException var4) {
            throw new IllegalArgumentException("Class " + StringUtil.simpleClassName(var1) + " does not have a class="kw">public non-arg constructor", var4);
         }
      }

      @Nonnull
      class="kw">public T newChannel() {
         try {
            class="kw">return (T)this.constructor.newInstance(this.family);
         } catch (Throwable var2) {
            throw new ChannelException("Unable to create Channel from class " + this.constructor.getDeclaringClass(), var2);
         }
      }

      @Nonnull
      class="kw">public String getSimpleName() {
         class="kw">return StringUtil.simpleClassName(this.constructor.getDeclaringClass()) + "(" + this.family + ")";
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return StringUtil.simpleClassName(io.netty.channel.ReflectiveChannelFactory.class)
            + "("
            + StringUtil.simpleClassName(this.constructor.getDeclaringClass())
            + ".class, "
            + this.family
            + ")";
      }
   }

   class="kw">public record TimeoutContext(@Nonnull String stage, long connectionStartNs, @Nonnull String playerIdentifier) {
      class="kw">public class="kw">static class="kw">final AttributeKey<NettyUtil.TimeoutContext> KEY = AttributeKey.newInstance("TIMEOUT_CONTEXT");

      class="kw">public TimeoutContext {
      }

      class="kw">public class="kw">static void init(@Nonnull Channel var0, @Nonnull String var1, @Nonnull String var2) {
         var0.attr(KEY).set(new NettyUtil.TimeoutContext(var1, System.nanoTime(), var2));
      }

      class="kw">public class="kw">static void update(@Nonnull Channel var0, @Nonnull String var1, @Nonnull String var2) {
         NettyUtil.TimeoutContext var3 = get(var0);
         var0.attr(KEY).set(new NettyUtil.TimeoutContext(var1, var3.connectionStartNs, var2));
      }

      class="kw">public class="kw">static void update(@Nonnull Channel var0, @Nonnull String var1) {
         NettyUtil.TimeoutContext var2 = get(var0);
         var0.attr(KEY).set(new NettyUtil.TimeoutContext(var1, var2.connectionStartNs, var2.playerIdentifier));
      }

      @Nonnull
      class="kw">public class="kw">static NettyUtil.TimeoutContext get(@Nonnull Channel var0) {
         NettyUtil.TimeoutContext var1 = (NettyUtil.TimeoutContext)var0.attr(KEY).get();
         if (var1 == null) {
            throw new IllegalStateException("TimeoutContext not initialized - this indicates a bug in the connection flow");
         } else {
            class="kw">return var1;
         }
      }
   }
}