Paper/src/main/java/net/minecraft/server/NetworkManager.java

211 Zeilen
7.4 KiB
Java

2011-03-27 22:12:39 +02:00
package net.minecraft.server;
import java.net.SocketAddress;
2013-07-09 01:43:37 +02:00
import java.util.Queue;
2012-07-29 09:33:13 +02:00
import javax.crypto.SecretKey;
2011-06-07 07:29:55 +02:00
2013-11-04 14:07:38 +01:00
import net.minecraft.util.com.google.common.collect.Queues;
import net.minecraft.util.com.google.common.util.concurrent.ThreadFactoryBuilder;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelFutureListener;
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
import net.minecraft.util.io.netty.channel.SimpleChannelInboundHandler;
import net.minecraft.util.io.netty.channel.local.LocalChannel;
import net.minecraft.util.io.netty.channel.local.LocalServerChannel;
import net.minecraft.util.io.netty.channel.nio.NioEventLoopGroup;
2014-04-16 04:45:03 +02:00
import net.minecraft.util.io.netty.handler.timeout.TimeoutException;
2013-11-04 14:07:38 +01:00
import net.minecraft.util.io.netty.util.AttributeKey;
import net.minecraft.util.io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.util.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;
public class NetworkManager extends SimpleChannelInboundHandler {
2014-03-21 05:26:30 +01:00
private static final Logger i = LogManager.getLogger();
2013-11-04 14:07:38 +01:00
public static final Marker a = MarkerManager.getMarker("NETWORK");
public static final Marker b = MarkerManager.getMarker("NETWORK_PACKETS", a);
2014-03-21 05:26:30 +01:00
public static final Marker c = MarkerManager.getMarker("NETWORK_STAT", a);
public static final AttributeKey d = new AttributeKey("protocol");
public static final AttributeKey e = new AttributeKey("receivable_packets");
public static final AttributeKey f = new AttributeKey("sendable_packets");
public static final NioEventLoopGroup g = new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build());
public static final NetworkStatistics h = new NetworkStatistics();
private final boolean j;
private final Queue k = Queues.newConcurrentLinkedQueue();
private final Queue l = Queues.newConcurrentLinkedQueue();
private Channel m;
private SocketAddress n;
private PacketListener o;
private EnumProtocol p;
private IChatBaseComponent q;
2014-04-11 03:04:38 +02:00
private boolean r;
2013-11-04 14:07:38 +01:00
public NetworkManager(boolean flag) {
2014-03-21 05:26:30 +01:00
this.j = flag;
2013-11-04 14:07:38 +01:00
}
public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception { // CraftBukkit - throws Exception
super.channelActive(channelhandlercontext);
2014-03-21 05:26:30 +01:00
this.m = channelhandlercontext.channel();
this.n = this.m.remoteAddress();
2013-11-04 14:07:38 +01:00
this.a(EnumProtocol.HANDSHAKING);
}
public void a(EnumProtocol enumprotocol) {
2014-03-21 05:26:30 +01:00
this.p = (EnumProtocol) this.m.attr(d).getAndSet(enumprotocol);
this.m.attr(e).set(enumprotocol.a(this.j));
this.m.attr(f).set(enumprotocol.b(this.j));
this.m.config().setAutoRead(true);
i.debug("Enabled auto read");
2013-11-04 14:07:38 +01:00
}
public void channelInactive(ChannelHandlerContext channelhandlercontext) {
2014-03-21 05:26:30 +01:00
this.close(new ChatMessage("disconnect.endOfStream", new Object[0]));
2013-11-04 14:07:38 +01:00
}
public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) {
2014-04-16 04:45:03 +02:00
ChatMessage chatmessage;
if (throwable instanceof TimeoutException) {
chatmessage = new ChatMessage("disconnect.timeout", new Object[0]);
} else {
chatmessage = new ChatMessage("disconnect.genericReason", new Object[] { "Internal Exception: " + throwable});
}
this.close(chatmessage);
2013-11-04 14:07:38 +01:00
}
protected void a(ChannelHandlerContext channelhandlercontext, Packet packet) {
2014-03-21 05:26:30 +01:00
if (this.m.isOpen()) {
2013-11-04 14:07:38 +01:00
if (packet.a()) {
2014-03-21 05:26:30 +01:00
packet.handle(this.o);
2013-11-04 14:07:38 +01:00
} else {
2014-03-21 05:26:30 +01:00
this.k.add(packet);
2011-03-27 22:12:39 +02:00
}
2011-05-28 22:50:08 +02:00
}
2011-03-27 22:12:39 +02:00
}
2013-11-04 14:07:38 +01:00
public void a(PacketListener packetlistener) {
Validate.notNull(packetlistener, "packetListener", new Object[0]);
2014-03-21 05:26:30 +01:00
i.debug("Set listener of {} to {}", new Object[] { this, packetlistener});
this.o = packetlistener;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public void handle(Packet packet, GenericFutureListener... agenericfuturelistener) {
2014-03-21 05:26:30 +01:00
if (this.m != null && this.m.isOpen()) {
2014-04-11 03:04:38 +02:00
this.i();
2013-11-04 14:07:38 +01:00
this.b(packet, agenericfuturelistener);
2012-07-29 09:33:13 +02:00
} else {
2014-03-21 05:26:30 +01:00
this.l.add(new QueuedPacket(packet, agenericfuturelistener));
2012-07-29 09:33:13 +02:00
}
}
2013-11-04 14:07:38 +01:00
private void b(Packet packet, GenericFutureListener[] agenericfuturelistener) {
EnumProtocol enumprotocol = EnumProtocol.a(packet);
2014-03-21 05:26:30 +01:00
EnumProtocol enumprotocol1 = (EnumProtocol) this.m.attr(d).get();
2012-07-29 09:33:13 +02:00
2013-11-04 14:07:38 +01:00
if (enumprotocol1 != enumprotocol) {
2014-03-21 05:26:30 +01:00
i.debug("Disabled auto read");
this.m.config().setAutoRead(false);
2012-07-29 09:33:13 +02:00
}
2014-03-21 05:26:30 +01:00
if (this.m.eventLoop().inEventLoop()) {
2013-11-04 14:07:38 +01:00
if (enumprotocol != enumprotocol1) {
this.a(enumprotocol);
2011-03-27 22:12:39 +02:00
}
2011-05-28 22:50:08 +02:00
2014-03-21 05:26:30 +01:00
this.m.writeAndFlush(packet).addListeners(agenericfuturelistener).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
2013-11-04 14:07:38 +01:00
} else {
2014-03-21 05:26:30 +01:00
this.m.eventLoop().execute(new QueuedProtocolSwitch(this, enumprotocol, enumprotocol1, packet, agenericfuturelistener));
2011-05-28 22:50:08 +02:00
}
2011-03-27 22:12:39 +02:00
}
2014-04-11 03:04:38 +02:00
private void i() {
2014-03-21 05:26:30 +01:00
if (this.m != null && this.m.isOpen()) {
while (!this.l.isEmpty()) {
QueuedPacket queuedpacket = (QueuedPacket) this.l.poll();
2011-03-27 22:12:39 +02:00
2013-11-04 14:07:38 +01:00
this.b(QueuedPacket.a(queuedpacket), QueuedPacket.b(queuedpacket));
2012-11-06 13:05:28 +01:00
}
2011-03-27 22:12:39 +02:00
}
}
2013-11-04 14:07:38 +01:00
public void a() {
2014-04-11 03:04:38 +02:00
this.i();
2014-03-21 05:26:30 +01:00
EnumProtocol enumprotocol = (EnumProtocol) this.m.attr(d).get();
2011-03-27 22:12:39 +02:00
2014-03-21 05:26:30 +01:00
if (this.p != enumprotocol) {
if (this.p != null) {
this.o.a(this.p, enumprotocol);
2011-03-27 22:12:39 +02:00
}
2013-11-04 14:07:38 +01:00
2014-03-21 05:26:30 +01:00
this.p = enumprotocol;
2011-03-27 22:12:39 +02:00
}
2014-03-21 05:26:30 +01:00
if (this.o != null) {
for (int i = 1000; !this.k.isEmpty() && i >= 0; --i) {
Packet packet = (Packet) this.k.poll();
2011-03-27 22:12:39 +02:00
2013-11-04 14:07:38 +01:00
// CraftBukkit start
2014-03-21 05:26:30 +01:00
if (!this.isConnected() || !this.m.config().isAutoRead()) {
2013-11-04 14:07:38 +01:00
continue;
}
// CraftBukkit end
2014-03-21 05:26:30 +01:00
packet.handle(this.o);
2012-09-10 06:19:28 +02:00
}
2014-03-21 05:26:30 +01:00
this.o.a();
2011-03-27 22:12:39 +02:00
}
2014-03-21 05:26:30 +01:00
this.m.flush();
2011-03-27 22:12:39 +02:00
}
public SocketAddress getSocketAddress() {
2014-03-21 05:26:30 +01:00
return this.n;
2011-03-27 22:12:39 +02:00
}
2014-03-21 05:26:30 +01:00
public void close(IChatBaseComponent ichatbasecomponent) {
if (this.m.isOpen()) {
this.m.close();
this.q = ichatbasecomponent;
2012-01-12 23:10:13 +01:00
}
2011-03-27 22:12:39 +02:00
}
2013-11-04 14:07:38 +01:00
public boolean c() {
2014-03-21 05:26:30 +01:00
return this.m instanceof LocalChannel || this.m instanceof LocalServerChannel;
2011-03-27 22:12:39 +02:00
}
2013-11-04 14:07:38 +01:00
public void a(SecretKey secretkey) {
2014-03-21 05:26:30 +01:00
this.m.pipeline().addBefore("splitter", "decrypt", new PacketDecrypter(MinecraftEncryption.a(2, secretkey)));
this.m.pipeline().addBefore("prepender", "encrypt", new PacketEncrypter(MinecraftEncryption.a(1, secretkey)));
2014-04-11 03:04:38 +02:00
this.r = true;
2011-03-27 22:12:39 +02:00
}
2014-03-21 05:26:30 +01:00
public boolean isConnected() {
return this.m != null && this.m.isOpen();
2011-03-27 22:12:39 +02:00
}
2013-11-04 14:07:38 +01:00
public PacketListener getPacketListener() {
2014-03-21 05:26:30 +01:00
return this.o;
2011-05-26 14:48:22 +02:00
}
2013-11-04 14:07:38 +01:00
public IChatBaseComponent f() {
2014-03-21 05:26:30 +01:00
return this.q;
2011-05-26 14:48:22 +02:00
}
2013-11-04 14:07:38 +01:00
public void g() {
2014-03-21 05:26:30 +01:00
this.m.config().setAutoRead(false);
2011-05-26 14:48:22 +02:00
}
2013-11-04 14:07:38 +01:00
protected void channelRead0(ChannelHandlerContext channelhandlercontext, Object object) {
this.a(channelhandlercontext, (Packet) object);
2011-03-27 22:12:39 +02:00
}
2013-11-04 14:07:38 +01:00
static Channel a(NetworkManager networkmanager) {
2014-03-21 05:26:30 +01:00
return networkmanager.m;
2011-03-27 22:12:39 +02:00
}
}