Update CraftBukkit to Minecraft 1.7.2
This commit is contained in:
@@ -1,377 +1,198 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import java.io.IOException; // CraftBukkit
|
||||
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;
|
||||
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 implements INetworkManager {
|
||||
public class NetworkManager extends SimpleChannelInboundHandler {
|
||||
|
||||
public static AtomicInteger a = new AtomicInteger();
|
||||
public static AtomicInteger b = new AtomicInteger();
|
||||
private final Object h = new Object();
|
||||
private final IConsoleLogManager i;
|
||||
public Socket socket; // CraftBukkit - private -> public
|
||||
private final SocketAddress k;
|
||||
private volatile DataInputStream input;
|
||||
private volatile DataOutputStream output;
|
||||
private volatile boolean n = true;
|
||||
private volatile boolean o;
|
||||
private Queue inboundQueue = new ConcurrentLinkedQueue();
|
||||
private List highPriorityQueue = Collections.synchronizedList(new ArrayList());
|
||||
private List lowPriorityQueue = Collections.synchronizedList(new ArrayList());
|
||||
private Connection connection;
|
||||
private boolean t;
|
||||
private Thread u;
|
||||
private Thread v;
|
||||
private String w = "";
|
||||
private Object[] x;
|
||||
private int y;
|
||||
private int z;
|
||||
public static int[] c = new int[256];
|
||||
public static int[] d = new int[256];
|
||||
public int e;
|
||||
boolean f;
|
||||
boolean g;
|
||||
private SecretKey A;
|
||||
private PrivateKey B;
|
||||
private int lowPriorityQueueDelay = 50;
|
||||
private static final Logger g = LogManager.getLogger();
|
||||
public static final Marker a = MarkerManager.getMarker("NETWORK");
|
||||
public static final Marker b = MarkerManager.getMarker("NETWORK_PACKETS", a);
|
||||
public static final AttributeKey c = new AttributeKey("protocol");
|
||||
public static final AttributeKey d = new AttributeKey("receivable_packets");
|
||||
public static final AttributeKey e = new AttributeKey("sendable_packets");
|
||||
public static final NioEventLoopGroup f = new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build());
|
||||
private final boolean h;
|
||||
private final Queue i = Queues.newConcurrentLinkedQueue();
|
||||
private final Queue j = Queues.newConcurrentLinkedQueue();
|
||||
private Channel k;
|
||||
private SocketAddress l;
|
||||
private PacketListener m;
|
||||
private EnumProtocol n;
|
||||
private IChatBaseComponent o;
|
||||
|
||||
public NetworkManager(IConsoleLogManager iconsolelogmanager, Socket socket, String s, Connection connection, PrivateKey privatekey) throws IOException { // CraftBukkit - throws IOException
|
||||
this.B = privatekey;
|
||||
this.socket = socket;
|
||||
this.i = iconsolelogmanager;
|
||||
this.k = socket.getRemoteSocketAddress();
|
||||
this.connection = connection;
|
||||
|
||||
try {
|
||||
socket.setSoTimeout(30000);
|
||||
socket.setTrafficClass(24);
|
||||
} catch (SocketException socketexception) {
|
||||
System.err.println(socketexception.getMessage());
|
||||
}
|
||||
|
||||
this.input = new DataInputStream(socket.getInputStream());
|
||||
this.output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), 5120));
|
||||
this.v = new NetworkReaderThread(this, s + " read thread");
|
||||
this.u = new NetworkWriterThread(this, s + " write thread");
|
||||
this.v.start();
|
||||
this.u.start();
|
||||
public NetworkManager(boolean flag) {
|
||||
this.h = flag;
|
||||
}
|
||||
|
||||
public void a(Connection connection) {
|
||||
this.connection = connection;
|
||||
public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception { // CraftBukkit - throws Exception
|
||||
super.channelActive(channelhandlercontext);
|
||||
this.k = channelhandlercontext.channel();
|
||||
this.l = this.k.remoteAddress();
|
||||
this.a(EnumProtocol.HANDSHAKING);
|
||||
}
|
||||
|
||||
public void queue(Packet packet) {
|
||||
if (!this.t) {
|
||||
Object object = this.h;
|
||||
public void a(EnumProtocol enumprotocol) {
|
||||
this.n = (EnumProtocol) this.k.attr(c).getAndSet(enumprotocol);
|
||||
this.k.attr(d).set(enumprotocol.a(this.h));
|
||||
this.k.attr(e).set(enumprotocol.b(this.h));
|
||||
this.k.config().setAutoRead(true);
|
||||
g.debug("Enabled auto read");
|
||||
}
|
||||
|
||||
synchronized (this.h) {
|
||||
this.z += packet.a() + 1;
|
||||
this.highPriorityQueue.add(packet);
|
||||
public void channelInactive(ChannelHandlerContext channelhandlercontext) {
|
||||
this.a((IChatBaseComponent) (new ChatMessage("disconnect.endOfStream", new Object[0])));
|
||||
}
|
||||
|
||||
public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) {
|
||||
this.a((IChatBaseComponent) (new ChatMessage("disconnect.genericReason", new Object[] { "Internal Exception: " + throwable})));
|
||||
}
|
||||
|
||||
protected void a(ChannelHandlerContext channelhandlercontext, Packet packet) {
|
||||
if (this.k.isOpen()) {
|
||||
if (packet.a()) {
|
||||
packet.handle(this.m);
|
||||
} else {
|
||||
this.i.add(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean h() {
|
||||
boolean flag = false;
|
||||
|
||||
try {
|
||||
Packet packet;
|
||||
int i;
|
||||
int[] aint;
|
||||
|
||||
if (this.e == 0 || !this.highPriorityQueue.isEmpty() && MinecraftServer.aq() - ((Packet) this.highPriorityQueue.get(0)).timestamp >= (long) this.e) {
|
||||
packet = this.a(false);
|
||||
if (packet != null) {
|
||||
Packet.a(packet, (DataOutput) this.output);
|
||||
if (packet instanceof Packet252KeyResponse && !this.g) {
|
||||
if (!this.connection.a()) {
|
||||
this.A = ((Packet252KeyResponse) packet).d();
|
||||
}
|
||||
|
||||
this.k();
|
||||
}
|
||||
|
||||
aint = d;
|
||||
i = packet.n();
|
||||
aint[i] += packet.a() + 1;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
// CraftBukkit - don't allow low priority packet to be sent unless it was placed in the queue before the first packet on the high priority queue TODO: is this still right?
|
||||
if ((flag || this.lowPriorityQueueDelay-- <= 0) && !this.lowPriorityQueue.isEmpty() && (this.highPriorityQueue.isEmpty() || ((Packet) this.highPriorityQueue.get(0)).timestamp > ((Packet) this.lowPriorityQueue.get(0)).timestamp)) {
|
||||
packet = this.a(true);
|
||||
if (packet != null) {
|
||||
Packet.a(packet, (DataOutput) this.output);
|
||||
aint = d;
|
||||
i = packet.n();
|
||||
aint[i] += packet.a() + 1;
|
||||
this.lowPriorityQueueDelay = 0;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
return flag;
|
||||
} catch (Exception exception) {
|
||||
if (!this.o) {
|
||||
this.a(exception);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public void a(PacketListener packetlistener) {
|
||||
Validate.notNull(packetlistener, "packetListener", new Object[0]);
|
||||
g.debug("Set listener of {} to {}", new Object[] { this, packetlistener});
|
||||
this.m = packetlistener;
|
||||
}
|
||||
|
||||
private Packet a(boolean flag) {
|
||||
Packet packet = null;
|
||||
List list = flag ? this.lowPriorityQueue : this.highPriorityQueue;
|
||||
Object object = this.h;
|
||||
|
||||
synchronized (this.h) {
|
||||
while (!list.isEmpty() && packet == null) {
|
||||
packet = (Packet) list.remove(0);
|
||||
this.z -= packet.a() + 1;
|
||||
if (this.a(packet, flag)) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean a(Packet packet, boolean flag) {
|
||||
if (!packet.e()) {
|
||||
return false;
|
||||
public void handle(Packet packet, GenericFutureListener... agenericfuturelistener) {
|
||||
if (this.k != null && this.k.isOpen()) {
|
||||
this.h();
|
||||
this.b(packet, agenericfuturelistener);
|
||||
} else {
|
||||
List list = flag ? this.lowPriorityQueue : this.highPriorityQueue;
|
||||
Iterator iterator = list.iterator();
|
||||
this.j.add(new QueuedPacket(packet, agenericfuturelistener));
|
||||
}
|
||||
}
|
||||
|
||||
Packet packet1;
|
||||
private void b(Packet packet, GenericFutureListener[] agenericfuturelistener) {
|
||||
EnumProtocol enumprotocol = EnumProtocol.a(packet);
|
||||
EnumProtocol enumprotocol1 = (EnumProtocol) this.k.attr(c).get();
|
||||
|
||||
do {
|
||||
if (!iterator.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
if (enumprotocol1 != enumprotocol) {
|
||||
g.debug("Disabled auto read");
|
||||
this.k.config().setAutoRead(false);
|
||||
}
|
||||
|
||||
packet1 = (Packet) iterator.next();
|
||||
} while (packet1.n() != packet.n());
|
||||
if (this.k.eventLoop().inEventLoop()) {
|
||||
if (enumprotocol != enumprotocol1) {
|
||||
this.a(enumprotocol);
|
||||
}
|
||||
|
||||
return packet.a(packet1);
|
||||
this.k.writeAndFlush(packet).addListeners(agenericfuturelistener).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
} else {
|
||||
this.k.eventLoop().execute(new QueuedProtocolSwitch(this, enumprotocol, enumprotocol1, packet, agenericfuturelistener));
|
||||
}
|
||||
}
|
||||
|
||||
private void h() {
|
||||
if (this.k != null && this.k.isOpen()) {
|
||||
while (!this.j.isEmpty()) {
|
||||
QueuedPacket queuedpacket = (QueuedPacket) this.j.poll();
|
||||
|
||||
this.b(QueuedPacket.a(queuedpacket), QueuedPacket.b(queuedpacket));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void a() {
|
||||
if (this.v != null) {
|
||||
this.v.interrupt();
|
||||
this.h();
|
||||
EnumProtocol enumprotocol = (EnumProtocol) this.k.attr(c).get();
|
||||
|
||||
if (this.n != enumprotocol) {
|
||||
if (this.n != null) {
|
||||
this.m.a(this.n, enumprotocol);
|
||||
}
|
||||
|
||||
this.n = enumprotocol;
|
||||
}
|
||||
|
||||
if (this.u != null) {
|
||||
this.u.interrupt();
|
||||
}
|
||||
}
|
||||
if (this.m != null) {
|
||||
for (int i = 1000; !this.i.isEmpty() && i >= 0; --i) {
|
||||
Packet packet = (Packet) this.i.poll();
|
||||
|
||||
private boolean i() {
|
||||
boolean flag = false;
|
||||
|
||||
try {
|
||||
Packet packet = Packet.a(this.i, this.input, this.connection.a(), this.socket);
|
||||
|
||||
if (packet != null) {
|
||||
if (packet instanceof Packet252KeyResponse && !this.f) {
|
||||
if (this.connection.a()) {
|
||||
this.A = ((Packet252KeyResponse) packet).a(this.B);
|
||||
}
|
||||
|
||||
this.j();
|
||||
// CraftBukkit start
|
||||
if (!this.d() || !this.k.config().isAutoRead()) { // Should be isConnected
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
int[] aint = c;
|
||||
int i = packet.n();
|
||||
|
||||
aint[i] += packet.a() + 1;
|
||||
if (!this.t) {
|
||||
if (packet.a_() && this.connection.b()) {
|
||||
this.y = 0;
|
||||
packet.handle(this.connection);
|
||||
} else {
|
||||
this.inboundQueue.add(packet);
|
||||
}
|
||||
}
|
||||
|
||||
flag = true;
|
||||
} else {
|
||||
this.a("disconnect.endOfStream", new Object[0]);
|
||||
packet.handle(this.m);
|
||||
}
|
||||
|
||||
return flag;
|
||||
} catch (Exception exception) {
|
||||
if (!this.o) {
|
||||
this.a(exception);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void a(Exception exception) {
|
||||
// exception.printStackTrace(); // CraftBukkit - Remove console spam
|
||||
this.a("disconnect.genericReason", new Object[] { "Internal exception: " + exception.toString()});
|
||||
}
|
||||
|
||||
public void a(String s, Object... aobject) {
|
||||
if (this.n) {
|
||||
this.o = true;
|
||||
this.w = s;
|
||||
this.x = aobject;
|
||||
this.n = false;
|
||||
(new NetworkMasterThread(this)).start();
|
||||
|
||||
try {
|
||||
this.input.close();
|
||||
} catch (Throwable throwable) {
|
||||
;
|
||||
}
|
||||
|
||||
try {
|
||||
this.output.close();
|
||||
} catch (Throwable throwable1) {
|
||||
;
|
||||
}
|
||||
|
||||
try {
|
||||
this.socket.close();
|
||||
} catch (Throwable throwable2) {
|
||||
;
|
||||
}
|
||||
|
||||
this.input = null;
|
||||
this.output = null;
|
||||
this.socket = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void b() {
|
||||
if (this.z > 2097152) {
|
||||
this.a("disconnect.overflow", new Object[0]);
|
||||
this.m.a();
|
||||
}
|
||||
|
||||
if (this.inboundQueue.isEmpty()) {
|
||||
if (this.y++ == 1200) {
|
||||
this.a("disconnect.timeout", new Object[0]);
|
||||
}
|
||||
} else {
|
||||
this.y = 0;
|
||||
}
|
||||
|
||||
int i = 1000;
|
||||
|
||||
while (!this.inboundQueue.isEmpty() && i-- >= 0) {
|
||||
Packet packet = (Packet) this.inboundQueue.poll();
|
||||
|
||||
// CraftBukkit start
|
||||
if (this.connection instanceof PendingConnection ? ((PendingConnection) this.connection).b : ((PlayerConnection) this.connection).disconnected) {
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
if (packet != null && !this.connection.c()) {
|
||||
packet.handle(this.connection);
|
||||
}
|
||||
}
|
||||
|
||||
this.a();
|
||||
if (this.o && this.inboundQueue.isEmpty()) {
|
||||
this.connection.a(this.w, this.x);
|
||||
}
|
||||
this.k.flush();
|
||||
}
|
||||
|
||||
public SocketAddress getSocketAddress() {
|
||||
return this.k;
|
||||
return this.l;
|
||||
}
|
||||
|
||||
public void d() {
|
||||
if (!this.t) {
|
||||
this.a();
|
||||
this.t = true;
|
||||
this.v.interrupt();
|
||||
(new NetworkMonitorThread(this)).start();
|
||||
public void a(IChatBaseComponent ichatbasecomponent) {
|
||||
if (this.k.isOpen()) {
|
||||
this.k.close();
|
||||
this.o = ichatbasecomponent;
|
||||
}
|
||||
}
|
||||
|
||||
private void j() throws IOException { // CraftBukkit - throws IOException
|
||||
this.f = true;
|
||||
InputStream inputstream = this.socket.getInputStream();
|
||||
|
||||
this.input = new DataInputStream(MinecraftEncryption.a(this.A, inputstream));
|
||||
public boolean c() {
|
||||
return this.k instanceof LocalChannel || this.k instanceof LocalServerChannel;
|
||||
}
|
||||
|
||||
private void k() throws IOException { // CraftBukkit - throws IOException
|
||||
this.output.flush();
|
||||
this.g = true;
|
||||
BufferedOutputStream bufferedoutputstream = new BufferedOutputStream(MinecraftEncryption.a(this.A, this.socket.getOutputStream()), 5120);
|
||||
|
||||
this.output = new DataOutputStream(bufferedoutputstream);
|
||||
public void a(SecretKey secretkey) {
|
||||
this.k.pipeline().addBefore("splitter", "decrypt", new PacketDecrypter(MinecraftEncryption.a(2, secretkey)));
|
||||
this.k.pipeline().addBefore("prepender", "encrypt", new PacketEncrypter(MinecraftEncryption.a(1, secretkey)));
|
||||
}
|
||||
|
||||
public int e() {
|
||||
return this.lowPriorityQueue.size();
|
||||
public boolean d() {
|
||||
return this.k != null && this.k.isOpen();
|
||||
}
|
||||
|
||||
public Socket getSocket() {
|
||||
return this.socket;
|
||||
public PacketListener getPacketListener() {
|
||||
return this.m;
|
||||
}
|
||||
|
||||
static boolean a(NetworkManager networkmanager) {
|
||||
return networkmanager.n;
|
||||
public IChatBaseComponent f() {
|
||||
return this.o;
|
||||
}
|
||||
|
||||
static boolean b(NetworkManager networkmanager) {
|
||||
return networkmanager.t;
|
||||
public void g() {
|
||||
this.k.config().setAutoRead(false);
|
||||
}
|
||||
|
||||
static boolean c(NetworkManager networkmanager) {
|
||||
return networkmanager.i();
|
||||
protected void channelRead0(ChannelHandlerContext channelhandlercontext, Object object) {
|
||||
this.a(channelhandlercontext, (Packet) object);
|
||||
}
|
||||
|
||||
static boolean d(NetworkManager networkmanager) {
|
||||
return networkmanager.h();
|
||||
}
|
||||
|
||||
static DataOutputStream e(NetworkManager networkmanager) {
|
||||
return networkmanager.output;
|
||||
}
|
||||
|
||||
static boolean f(NetworkManager networkmanager) {
|
||||
return networkmanager.o;
|
||||
}
|
||||
|
||||
static void a(NetworkManager networkmanager, Exception exception) {
|
||||
networkmanager.a(exception);
|
||||
}
|
||||
|
||||
static Thread g(NetworkManager networkmanager) {
|
||||
return networkmanager.v;
|
||||
}
|
||||
|
||||
static Thread h(NetworkManager networkmanager) {
|
||||
return networkmanager.u;
|
||||
static Channel a(NetworkManager networkmanager) {
|
||||
return networkmanager.k;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user