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

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

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) throws Exception {
    this.close(new ChatMessage("disconnect.endOfStream"));
  }

  public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) throws Exception {
    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 cancelledpackethandleexception) {
      }
    }

  }

  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(new Runnable() {
        public void run() {
          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