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

290 Zeilen
8.1 KiB
Java

2011-03-27 22:12:39 +02:00
package net.minecraft.server;
2011-04-20 22:47:26 +02:00
import java.io.BufferedOutputStream;
2011-03-27 22:12:39 +02:00
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.net.SocketAddress;
2011-06-12 00:02:58 +02:00
import java.net.SocketException;
2011-03-27 22:12:39 +02:00
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
2011-06-07 07:29:55 +02:00
2011-03-27 22:12:39 +02:00
public class NetworkManager {
public static final Object a = new Object();
public static int b;
public static int c;
2011-05-26 14:48:22 +02:00
private Object g = new Object();
2011-05-14 16:29:42 +02:00
public Socket socket; // CraftBukkit - private -> public
2011-05-26 14:48:22 +02:00
private final SocketAddress i;
private DataInputStream input;
private DataOutputStream output;
2011-05-26 14:48:22 +02:00
private boolean l = true;
2011-03-27 22:12:39 +02:00
private List m = Collections.synchronizedList(new ArrayList());
private List highPriorityQueue = Collections.synchronizedList(new ArrayList());
private List lowPriorityQueue = Collections.synchronizedList(new ArrayList());
2011-05-26 14:48:22 +02:00
private NetHandler p;
private boolean q = false;
private Thread r;
private Thread s;
private boolean t = false;
private String u = "";
private Object[] v;
private int w = 0;
private int x = 0;
public static int[] d = new int[256];
public static int[] e = new int[256];
public int f = 0;
private int lowPriorityQueueDelay = 50;
2011-03-27 22:12:39 +02:00
public NetworkManager(Socket socket, String s, NetHandler nethandler) {
this.socket = socket;
2011-05-26 14:48:22 +02:00
this.i = socket.getRemoteSocketAddress();
this.p = nethandler;
2011-03-27 22:12:39 +02:00
2011-06-07 07:29:55 +02:00
// CraftBukkit start - IPv6 stack in Java on BSD/OSX doesn't support setTrafficClass
2011-03-27 22:12:39 +02:00
try {
socket.setTrafficClass(24);
2011-06-12 00:02:58 +02:00
} catch (SocketException e) {}
2011-06-07 07:29:55 +02:00
// CraftBukkit end
2011-04-20 22:47:26 +02:00
2011-06-07 07:29:55 +02:00
try {
2011-05-14 16:29:42 +02:00
// CraftBukkit start - cant compile these outside the try
2011-06-07 07:29:55 +02:00
socket.setSoTimeout(30000);
this.input = new DataInputStream(socket.getInputStream());
2011-05-28 22:50:08 +02:00
this.output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), 5120));
} catch (java.io.IOException socketexception) {
2011-04-20 22:47:26 +02:00
// CraftBukkit end
2011-03-31 22:40:00 +02:00
System.err.println(socketexception.getMessage());
}
2011-03-27 22:12:39 +02:00
/* CraftBukkit start - moved up
this.input = new DataInputStream(socket.getInputStream());
this.output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), 5120));
// CraftBukkit end */
2011-05-26 14:48:22 +02:00
this.s = new NetworkReaderThread(this, s + " read thread");
this.r = new NetworkWriterThread(this, s + " write thread");
this.s.start();
this.r.start();
2011-03-27 22:12:39 +02:00
}
public void a(NetHandler nethandler) {
2011-05-26 14:48:22 +02:00
this.p = nethandler;
2011-03-27 22:12:39 +02:00
}
public void queue(Packet packet) {
2011-05-26 14:48:22 +02:00
if (!this.q) {
Object object = this.g;
2011-03-27 22:12:39 +02:00
2011-05-26 14:48:22 +02:00
synchronized (this.g) {
this.x += packet.a() + 1;
2011-11-20 09:01:14 +01:00
if (packet.l) {
this.lowPriorityQueue.add(packet);
2011-03-27 22:12:39 +02:00
} else {
this.highPriorityQueue.add(packet);
2011-03-27 22:12:39 +02:00
}
}
}
}
2011-09-15 02:23:52 +02:00
private boolean g() {
2011-05-26 16:20:11 +02:00
boolean flag = false;
2011-03-27 22:12:39 +02:00
try {
Object object;
Packet packet;
2011-05-26 14:48:22 +02:00
int i;
int[] aint;
if (!this.highPriorityQueue.isEmpty() && (this.f == 0 || System.currentTimeMillis() - ((Packet) this.highPriorityQueue.get(0)).timestamp >= (long) this.f)) {
object = this.g;
synchronized (this.g) {
packet = (Packet) this.highPriorityQueue.remove(0);
2011-05-26 14:48:22 +02:00
this.x -= packet.a() + 1;
}
Packet.a(packet, this.output);
aint = e;
i = packet.b();
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
if ((flag || this.lowPriorityQueueDelay-- <= 0) && !this.lowPriorityQueue.isEmpty() && (this.highPriorityQueue.isEmpty() || ((Packet) this.highPriorityQueue.get(0)).timestamp > ((Packet) this.lowPriorityQueue.get(0)).timestamp)) {
object = this.g;
synchronized (this.g) {
packet = (Packet) this.lowPriorityQueue.remove(0);
2011-05-26 14:48:22 +02:00
this.x -= packet.a() + 1;
2011-03-27 22:12:39 +02:00
}
Packet.a(packet, this.output);
2011-05-26 14:48:22 +02:00
aint = e;
i = packet.b();
2011-05-28 22:50:08 +02:00
aint[i] += packet.a() + 1;
this.lowPriorityQueueDelay = 0;
2011-05-26 16:20:11 +02:00
flag = true;
2011-03-27 22:12:39 +02:00
}
2011-05-28 22:50:08 +02:00
return flag;
2011-03-27 22:12:39 +02:00
} catch (Exception exception) {
2011-05-26 14:48:22 +02:00
if (!this.t) {
2011-03-27 22:12:39 +02:00
this.a(exception);
}
2011-05-26 16:20:11 +02:00
2011-05-28 22:50:08 +02:00
return false;
}
2011-03-27 22:12:39 +02:00
}
2011-05-26 14:48:22 +02:00
public void a() {
2011-05-28 22:50:08 +02:00
this.s.interrupt();
this.r.interrupt();
2011-05-26 14:48:22 +02:00
}
2011-09-15 02:23:52 +02:00
private boolean h() {
2011-05-26 16:20:11 +02:00
boolean flag = false;
2011-03-27 22:12:39 +02:00
try {
2011-05-26 14:48:22 +02:00
Packet packet = Packet.a(this.input, this.p.c());
2011-03-27 22:12:39 +02:00
if (packet != null) {
2011-05-26 14:48:22 +02:00
int[] aint = d;
int i = packet.b();
2011-05-28 22:50:08 +02:00
aint[i] += packet.a() + 1;
2011-05-26 14:48:22 +02:00
this.m.add(packet);
2011-05-26 16:20:11 +02:00
flag = true;
2011-03-27 22:12:39 +02:00
} else {
this.a("disconnect.endOfStream", new Object[0]);
}
2011-05-28 22:50:08 +02:00
return flag;
2011-03-27 22:12:39 +02:00
} catch (Exception exception) {
2011-05-26 14:48:22 +02:00
if (!this.t) {
2011-03-27 22:12:39 +02:00
this.a(exception);
}
2011-05-26 16:20:11 +02:00
2011-05-28 22:50:08 +02:00
return false;
}
2011-03-27 22:12:39 +02:00
}
private void a(Exception exception) {
exception.printStackTrace();
this.a("disconnect.genericReason", new Object[] { "Internal exception: " + exception.toString()});
}
public void a(String s, Object... aobject) {
2011-05-26 14:48:22 +02:00
if (this.l) {
this.t = true;
this.u = s;
this.v = aobject;
2011-03-27 22:12:39 +02:00
(new NetworkMasterThread(this)).start();
2011-05-26 14:48:22 +02:00
this.l = false;
2011-03-27 22:12:39 +02:00
try {
this.input.close();
this.input = null;
2011-03-27 22:12:39 +02:00
} catch (Throwable throwable) {
;
}
try {
this.output.close();
this.output = null;
2011-03-27 22:12:39 +02:00
} catch (Throwable throwable1) {
;
}
try {
this.socket.close();
this.socket = null;
2011-03-27 22:12:39 +02:00
} catch (Throwable throwable2) {
;
}
}
}
2011-05-26 14:48:22 +02:00
public void b() {
if (this.x > 1048576) {
2011-03-27 22:12:39 +02:00
this.a("disconnect.overflow", new Object[0]);
}
2011-05-26 14:48:22 +02:00
if (this.m.isEmpty()) {
if (this.w++ == 1200) {
2011-03-27 22:12:39 +02:00
this.a("disconnect.timeout", new Object[0]);
}
} else {
2011-05-26 14:48:22 +02:00
this.w = 0;
2011-03-27 22:12:39 +02:00
}
2011-09-15 02:23:52 +02:00
int i = 1000;
2011-03-27 22:12:39 +02:00
2011-05-26 14:48:22 +02:00
while (!this.m.isEmpty() && i-- >= 0) {
Packet packet = (Packet) this.m.remove(0);
2011-03-27 22:12:39 +02:00
2011-05-26 14:48:22 +02:00
packet.a(this.p);
2011-03-27 22:12:39 +02:00
}
2011-05-28 22:50:08 +02:00
this.a();
2011-05-26 14:48:22 +02:00
if (this.t && this.m.isEmpty()) {
this.p.a(this.u, this.v);
2011-03-27 22:12:39 +02:00
}
}
public SocketAddress getSocketAddress() {
2011-05-26 14:48:22 +02:00
return this.i;
2011-03-27 22:12:39 +02:00
}
2011-05-26 14:48:22 +02:00
public void d() {
this.a();
this.q = true;
this.s.interrupt();
2011-03-27 22:12:39 +02:00
(new ThreadMonitorConnection(this)).start();
}
2011-05-26 14:48:22 +02:00
public int e() {
return this.lowPriorityQueue.size();
2011-03-27 22:12:39 +02:00
}
2011-09-15 02:23:52 +02:00
public Socket f() {
return this.socket;
}
2011-03-27 22:12:39 +02:00
static boolean a(NetworkManager networkmanager) {
2011-05-26 14:48:22 +02:00
return networkmanager.l;
2011-03-27 22:12:39 +02:00
}
static boolean b(NetworkManager networkmanager) {
2011-05-26 14:48:22 +02:00
return networkmanager.q;
2011-03-27 22:12:39 +02:00
}
2011-05-26 16:20:11 +02:00
static boolean c(NetworkManager networkmanager) {
2011-09-15 02:23:52 +02:00
return networkmanager.h();
2011-03-27 22:12:39 +02:00
}
2011-05-26 16:20:11 +02:00
static boolean d(NetworkManager networkmanager) {
2011-09-15 02:23:52 +02:00
return networkmanager.g();
2011-03-27 22:12:39 +02:00
}
2011-05-28 22:50:08 +02:00
static DataOutputStream e(NetworkManager networkmanager) {
return networkmanager.output;
2011-05-26 14:48:22 +02:00
}
2011-05-28 22:50:08 +02:00
static boolean f(NetworkManager networkmanager) {
return networkmanager.t;
2011-05-26 14:48:22 +02:00
}
2011-05-28 22:50:08 +02:00
static void a(NetworkManager networkmanager, Exception exception) {
networkmanager.a(exception);
2011-05-26 14:48:22 +02:00
}
static Thread g(NetworkManager networkmanager) {
return networkmanager.s;
2011-03-27 22:12:39 +02:00
}
2011-05-26 14:48:22 +02:00
static Thread h(NetworkManager networkmanager) {
return networkmanager.r;
2011-03-27 22:12:39 +02:00
}
}