All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.minecraft.server.NetworkManager Maven / Gradle / Ivy

There is a newer version: 2.4.0
Show newest version
package net.minecraft.server;

import com.google.common.collect.Queues;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.netty.channel.*;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalEventLoopGroup;
import io.netty.channel.local.LocalServerChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.timeout.TimeoutException;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;

import javax.crypto.SecretKey;
import java.net.SocketAddress;
import java.util.Queue;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class NetworkManager extends SimpleChannelInboundHandler {

   public static final Marker a = MarkerManager.getMarker("NETWORK");
   public static final Marker b = MarkerManager.getMarker("NETWORK_PACKETS", NetworkManager.a);
   public static final AttributeKey c = AttributeKey.valueOf("protocol");
   public static final LazyInitVar d = new LazyInitVar() {
      protected NioEventLoopGroup a() {
         return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build());
      }

      protected Object init() {
         return this.a();
      }
   };
   public static final LazyInitVar e = new LazyInitVar() {
      protected EpollEventLoopGroup a() {
         return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Client IO #%d").setDaemon(true).build());
      }

      protected Object init() {
         return this.a();
      }
   };
   public static final LazyInitVar f = new LazyInitVar() {
      protected LocalEventLoopGroup a() {
         return new LocalEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).build());
      }

      protected Object init() {
         return this.a();
      }
   };
   private static final Logger g = LogManager.getLogger();
   private final EnumProtocolDirection h;
   private final Queue i = Queues.newConcurrentLinkedQueue();
   private final ReentrantReadWriteLock j = new ReentrantReadWriteLock();
   public Channel channel;
   // Spigot Start // PAIL
   public SocketAddress l;
   public java.util.UUID spoofedUUID;
   public com.mojang.authlib.properties.Property[] spoofedProfile;
   public boolean preparing = true;
   // Spigot End
   private PacketListener m;
   private IChatBaseComponent n;
   private boolean o;
   private boolean p;

   public NetworkManager(EnumProtocolDirection enumprotocoldirection) {
      this.h = enumprotocoldirection;
   }

   public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception {
      super.channelActive(channelhandlercontext);
      this.channel = channelhandlercontext.channel();
      this.l = this.channel.remoteAddress();
      // Spigot Start
      this.preparing = false;
      // Spigot End

      try {
         this.a(EnumProtocol.HANDSHAKING);
      } catch (Throwable throwable) {
         NetworkManager.g.fatal(throwable);
      }

   }

   public void a(EnumProtocol enumprotocol) {
      this.channel.attr(NetworkManager.c).set(enumprotocol);
      this.channel.config().setAutoRead(true);
      NetworkManager.g.debug("Enabled auto read");
   }

   public void channelInactive(ChannelHandlerContext channelhandlercontext) {
      this.close(new ChatMessage("disconnect.endOfStream"));
   }

   public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) {
      ChatMessage chatmessage;

      if (throwable instanceof TimeoutException) {
         chatmessage = new ChatMessage("disconnect.timeout");
      } else {
         chatmessage = new ChatMessage("disconnect.genericReason", "Internal Exception: " + throwable);
      }

      this.close(chatmessage);
      if (MinecraftServer.getServer().isDebugging()) throwable.printStackTrace(); // Spigot
   }

   protected void a(ChannelHandlerContext channelhandlercontext, Packet packet) throws Exception {
      if (this.channel.isOpen()) {
         try {
            packet.a(this.m);
         } catch (CancelledPacketHandleException ignored) {
         }
      }

   }

   public void a(PacketListener packetlistener) {
      Validate.notNull(packetlistener, "packetListener");
      NetworkManager.g.debug("Set listener of {} to {}", this, packetlistener);
      this.m = packetlistener;
   }

   public void handle(Packet packet) {
      if (this.g()) {
         this.m();
         this.a(packet, null);
      } else {
         this.j.writeLock().lock();

         try {
            this.i.add(new NetworkManager.QueuedPacket(packet, (GenericFutureListener[]) null));
         } finally {
            this.j.writeLock().unlock();
         }
      }

   }

   public void a(Packet packet, GenericFutureListener> genericfuturelistener, GenericFutureListener>... agenericfuturelistener) {
      if (this.g()) {
         this.m();
         this.a(packet, ArrayUtils.add(agenericfuturelistener, 0, genericfuturelistener));
      } else {
         this.j.writeLock().lock();

         try {
            this.i.add(new NetworkManager.QueuedPacket(packet, ArrayUtils.add(agenericfuturelistener, 0, genericfuturelistener)));
         } finally {
            this.j.writeLock().unlock();
         }
      }

   }

   private void a(final Packet packet, final GenericFutureListener>[] agenericfuturelistener) {
      final EnumProtocol enumprotocol = EnumProtocol.a(packet);
      final EnumProtocol enumprotocol1 = this.channel.attr(NetworkManager.c).get();

      if (enumprotocol1 != enumprotocol) {
         NetworkManager.g.debug("Disabled auto read");
         this.channel.config().setAutoRead(false);
      }

      if (this.channel.eventLoop().inEventLoop()) {
         if (enumprotocol != enumprotocol1) {
            this.a(enumprotocol);
         }

         ChannelFuture channelfuture = this.channel.writeAndFlush(packet);

         if (agenericfuturelistener != null) {
            channelfuture.addListeners(agenericfuturelistener);
         }

         channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
      } else {
         this.channel.eventLoop().execute(() -> {
            if (enumprotocol != enumprotocol1) {
               NetworkManager.this.a(enumprotocol);
            }

            ChannelFuture channelfuture = NetworkManager.this.channel.writeAndFlush(packet);

            if (agenericfuturelistener != null) {
               channelfuture.addListeners(agenericfuturelistener);
            }

            channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
         });
      }

   }

   private void m() {
      if (this.channel != null && this.channel.isOpen()) {
         this.j.readLock().lock();

         try {
            while (!this.i.isEmpty()) {
               NetworkManager.QueuedPacket networkmanager_queuedpacket = this.i.poll();

               this.a(networkmanager_queuedpacket.a, networkmanager_queuedpacket.b);
            }
         } finally {
            this.j.readLock().unlock();
         }

      }
   }

   public void a() {
      this.m();
      if (this.m instanceof IUpdatePlayerListBox) {
         ((IUpdatePlayerListBox) this.m).c();
      }

      this.channel.flush();
   }

   public SocketAddress getSocketAddress() {
      return this.l;
   }

   public void close(IChatBaseComponent ichatbasecomponent) {
      // Spigot Start
      this.preparing = false;
      // Spigot End
      if (this.channel.isOpen()) {
         this.channel.close(); // We can't wait as this may be called from an event loop.
         this.n = ichatbasecomponent;
      }

   }

   public boolean c() {
      return this.channel instanceof LocalChannel || this.channel instanceof LocalServerChannel;
   }

   public void a(SecretKey secretkey) {
      this.o = true;
      this.channel.pipeline().addBefore("splitter", "decrypt", new PacketDecrypter(MinecraftEncryption.a(2, secretkey)));
      this.channel.pipeline().addBefore("prepender", "encrypt", new PacketEncrypter(MinecraftEncryption.a(1, secretkey)));
   }

   public boolean g() {
      return this.channel != null && this.channel.isOpen();
   }

   public boolean h() {
      return this.channel == null;
   }

   public PacketListener getPacketListener() {
      return this.m;
   }

   public IChatBaseComponent j() {
      return this.n;
   }

   public void k() {
      this.channel.config().setAutoRead(false);
   }

   public void a(int i) {
      if (i >= 0) {
         if (this.channel.pipeline().get("decompress") instanceof PacketDecompressor) {
            ((PacketDecompressor) this.channel.pipeline().get("decompress")).a(i);
         } else {
            this.channel.pipeline().addBefore("decoder", "decompress", new PacketDecompressor(i));
         }

         if (this.channel.pipeline().get("compress") instanceof PacketCompressor) {
            ((PacketCompressor) this.channel.pipeline().get("decompress")).a(i);
         } else {
            this.channel.pipeline().addBefore("encoder", "compress", new PacketCompressor(i));
         }
      } else {
         if (this.channel.pipeline().get("decompress") instanceof PacketDecompressor) {
            this.channel.pipeline().remove("decompress");
         }

         if (this.channel.pipeline().get("compress") instanceof PacketCompressor) {
            this.channel.pipeline().remove("compress");
         }
      }

   }

   public void l() {
      if (this.channel != null && !this.channel.isOpen()) {
         if (!this.p) {
            this.p = true;
            if (this.j() != null) {
               this.getPacketListener().a(this.j());
            } else if (this.getPacketListener() != null) {
               this.getPacketListener().a(new ChatComponentText("Disconnected"));
            }
            this.i.clear(); // Free up packet queue.
         } else {
            NetworkManager.g.warn("handleDisconnection() called twice");
         }

      }
   }

   protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet object) throws Exception { // CraftBukkit - fix decompile error
      this.a(channelhandlercontext, object);
   }

   // Spigot Start
   public SocketAddress getRawAddress() {
      return this.channel.remoteAddress();
   }

   static class QueuedPacket {

      private final Packet a;
      private final GenericFutureListener>[] b;

      public QueuedPacket(Packet packet, GenericFutureListener>... agenericfuturelistener) {
         this.a = packet;
         this.b = agenericfuturelistener;
      }
   }
   // Spigot End
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy