2011-03-27 22:12:39 +02:00
|
|
|
package net.minecraft.server;
|
|
|
|
|
2011-04-20 22:47:26 +02:00
|
|
|
import java.io.BufferedInputStream;
|
|
|
|
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-04-20 22:47:26 +02:00
|
|
|
import java.io.IOException; // CraftBukkit -- instead of SocketException
|
2011-03-27 22:12:39 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
2011-04-20 19:05:14 +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;
|
|
|
|
private Object e = new Object();
|
2011-04-20 19:05:14 +02:00
|
|
|
public Socket socket; // CraftBukkit -- private->public
|
2011-03-27 22:12:39 +02:00
|
|
|
private final SocketAddress g;
|
2011-04-20 19:05:14 +02:00
|
|
|
private DataInputStream input;
|
|
|
|
private DataOutputStream output;
|
2011-03-27 22:12:39 +02:00
|
|
|
private boolean j = true;
|
|
|
|
private List k = Collections.synchronizedList(new ArrayList());
|
|
|
|
private List l = Collections.synchronizedList(new ArrayList());
|
|
|
|
private List m = Collections.synchronizedList(new ArrayList());
|
|
|
|
private NetHandler n;
|
|
|
|
private boolean o = false;
|
|
|
|
private Thread p;
|
|
|
|
private Thread q;
|
|
|
|
private boolean r = false;
|
|
|
|
private String s = "";
|
|
|
|
private Object[] t;
|
|
|
|
private int u = 0;
|
|
|
|
private int v = 0;
|
|
|
|
public int d = 0;
|
|
|
|
private int w = 50;
|
|
|
|
|
|
|
|
public NetworkManager(Socket socket, String s, NetHandler nethandler) {
|
2011-04-20 19:05:14 +02:00
|
|
|
this.socket = socket;
|
2011-03-27 22:12:39 +02:00
|
|
|
this.g = socket.getRemoteSocketAddress();
|
|
|
|
this.n = nethandler;
|
|
|
|
|
|
|
|
try {
|
2011-04-20 22:47:26 +02:00
|
|
|
socket.setSoTimeout(30000);
|
2011-03-27 22:12:39 +02:00
|
|
|
socket.setTrafficClass(24);
|
2011-04-20 22:47:26 +02:00
|
|
|
|
|
|
|
// CraftBukkit start -- cant compile these outside the try
|
2011-04-20 19:05:14 +02:00
|
|
|
this.input = new DataInputStream(socket.getInputStream());
|
|
|
|
this.output = new DataOutputStream(socket.getOutputStream());
|
2011-04-20 22:47:26 +02:00
|
|
|
// CraftBukkit end
|
2011-04-20 19:05:14 +02:00
|
|
|
} catch (IOException socketexception) {
|
2011-03-31 22:40:00 +02:00
|
|
|
System.err.println(socketexception.getMessage());
|
|
|
|
}
|
2011-03-27 22:12:39 +02:00
|
|
|
|
|
|
|
this.q = new NetworkReaderThread(this, s + " read thread");
|
|
|
|
this.p = new NetworkWriterThread(this, s + " write thread");
|
|
|
|
this.q.start();
|
|
|
|
this.p.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void a(NetHandler nethandler) {
|
|
|
|
this.n = nethandler;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void a(Packet packet) {
|
|
|
|
if (!this.o) {
|
|
|
|
Object object = this.e;
|
|
|
|
|
|
|
|
synchronized (this.e) {
|
|
|
|
this.v += packet.a() + 1;
|
|
|
|
if (packet.k) {
|
|
|
|
this.m.add(packet);
|
|
|
|
} else {
|
|
|
|
this.l.add(packet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void e() {
|
|
|
|
try {
|
|
|
|
boolean flag = true;
|
|
|
|
Object object;
|
|
|
|
Packet packet;
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
if (!this.l.isEmpty() && (this.d == 0 || System.currentTimeMillis() - ((Packet) this.l.get(0)).timestamp >= (long) this.d)) {
|
2011-03-27 22:12:39 +02:00
|
|
|
flag = false;
|
|
|
|
object = this.e;
|
|
|
|
synchronized (this.e) {
|
|
|
|
packet = (Packet) this.l.remove(0);
|
|
|
|
this.v -= packet.a() + 1;
|
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
Packet.a(packet, this.output);
|
2011-03-27 22:12:39 +02:00
|
|
|
}
|
|
|
|
|
2011-05-05 04:06:08 +02:00
|
|
|
// 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.w-- <= 0) && !this.m.isEmpty() && (this.l.isEmpty() || ((Packet) this.l.get(0)).timestamp > ((Packet) this.m.get(0)).timestamp)) {
|
2011-03-27 22:12:39 +02:00
|
|
|
flag = false;
|
|
|
|
object = this.e;
|
|
|
|
synchronized (this.e) {
|
|
|
|
packet = (Packet) this.m.remove(0);
|
|
|
|
this.v -= packet.a() + 1;
|
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
Packet.a(packet, this.output);
|
2011-03-27 22:12:39 +02:00
|
|
|
this.w = 50;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag) {
|
|
|
|
Thread.sleep(10L);
|
2011-04-20 22:47:26 +02:00
|
|
|
} else {
|
|
|
|
this.output.flush();
|
2011-03-27 22:12:39 +02:00
|
|
|
}
|
|
|
|
} catch (InterruptedException interruptedexception) {
|
|
|
|
;
|
|
|
|
} catch (Exception exception) {
|
|
|
|
if (!this.r) {
|
|
|
|
this.a(exception);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void f() {
|
|
|
|
try {
|
2011-04-20 22:47:26 +02:00
|
|
|
Packet packet = Packet.a(this.input, this.n.c());
|
2011-03-27 22:12:39 +02:00
|
|
|
|
|
|
|
if (packet != null) {
|
|
|
|
this.k.add(packet);
|
|
|
|
} else {
|
|
|
|
this.a("disconnect.endOfStream", new Object[0]);
|
|
|
|
}
|
|
|
|
} catch (Exception exception) {
|
|
|
|
if (!this.r) {
|
|
|
|
this.a(exception);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void a(Exception exception) {
|
|
|
|
exception.printStackTrace();
|
|
|
|
this.a("disconnect.genericReason", new Object[] { "Internal exception: " + exception.toString()});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void a(String s, Object... aobject) {
|
|
|
|
if (this.j) {
|
|
|
|
this.r = true;
|
|
|
|
this.s = s;
|
|
|
|
this.t = aobject;
|
|
|
|
(new NetworkMasterThread(this)).start();
|
|
|
|
this.j = false;
|
|
|
|
|
|
|
|
try {
|
2011-04-20 19:05:14 +02:00
|
|
|
this.input.close();
|
|
|
|
this.input = null;
|
2011-03-27 22:12:39 +02:00
|
|
|
} catch (Throwable throwable) {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2011-04-20 19:05:14 +02:00
|
|
|
this.output.close();
|
|
|
|
this.output = null;
|
2011-03-27 22:12:39 +02:00
|
|
|
} catch (Throwable throwable1) {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2011-04-20 19:05:14 +02:00
|
|
|
this.socket.close();
|
|
|
|
this.socket = null;
|
2011-03-27 22:12:39 +02:00
|
|
|
} catch (Throwable throwable2) {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void a() {
|
|
|
|
if (this.v > 1048576) {
|
|
|
|
this.a("disconnect.overflow", new Object[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.k.isEmpty()) {
|
|
|
|
if (this.u++ == 1200) {
|
|
|
|
this.a("disconnect.timeout", new Object[0]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.u = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int i = 100;
|
|
|
|
|
|
|
|
while (!this.k.isEmpty() && i-- >= 0) {
|
|
|
|
Packet packet = (Packet) this.k.remove(0);
|
|
|
|
|
|
|
|
packet.a(this.n);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.r && this.k.isEmpty()) {
|
|
|
|
this.n.a(this.s, this.t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
public SocketAddress getSocketAddress() {
|
2011-03-27 22:12:39 +02:00
|
|
|
return this.g;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void c() {
|
|
|
|
this.o = true;
|
|
|
|
this.q.interrupt();
|
|
|
|
(new ThreadMonitorConnection(this)).start();
|
|
|
|
}
|
|
|
|
|
|
|
|
public int d() {
|
|
|
|
return this.m.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
static boolean a(NetworkManager networkmanager) {
|
|
|
|
return networkmanager.j;
|
|
|
|
}
|
|
|
|
|
|
|
|
static boolean b(NetworkManager networkmanager) {
|
|
|
|
return networkmanager.o;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void c(NetworkManager networkmanager) {
|
|
|
|
networkmanager.f();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void d(NetworkManager networkmanager) {
|
|
|
|
networkmanager.e();
|
|
|
|
}
|
|
|
|
|
|
|
|
static Thread e(NetworkManager networkmanager) {
|
|
|
|
return networkmanager.q;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Thread f(NetworkManager networkmanager) {
|
|
|
|
return networkmanager.p;
|
|
|
|
}
|
|
|
|
}
|