package polly.mud.connection;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import de.skuzzle.jeve.EventProvider;
public class MudTCPConnection implements Closeable {
public static MudTCPConnection connect(String host, int port,
ConnectionListener callback) throws UnknownHostException, IOException {
final MudTCPConnection result = new MudTCPConnection(host, port);
if (callback != null) {
result.addConnectionListener(callback);
}
result.connect();
return result;
}
private Socket socket;
private BufferedReader in;
private BufferedWriter out;
private Thread receiver;
private final EventProvider events = EventProvider.newDefaultEventProvider();
private final String host;
private final int port;
private MudTCPConnection(String host, int port) {
this.host = host;
this.port = port;
}
public synchronized void connect() throws IOException {
if (this.socket != null && this.socket.isConnected()) {
return;
}
this.socket = new Socket(this.host, this.port);
this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
this.out = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
this.receiver = new Thread("RECEIVER") {
@Override
public void run() {
while (!this.isInterrupted()) {
try {
final String line = in.readLine();
if (line == null) {
break;
}
fireMessageReceived(line);
} catch (IOException e) {
break;
}
}
fireDiconnected();
}
};
this.receiver.start();
this.fireConnected();
}
public void send(String message) {
try {
this.out.write(message);
this.out.flush();
} catch (IOException e) {
this.fireDiconnected();
}
}
public void submit(String message) {
this.send(message + "\r\n");
}
private void fireMessageReceived(final String s) {
final MudMessageEvent e = new MudMessageEvent(this, s);
this.events.dispatch(ConnectionListener.class, e,
ConnectionListener::received);
}
private void fireConnected() {
final MudEvent e = new MudEvent(this);
this.events.dispatch(ConnectionListener.class, e,
ConnectionListener::connected);
}
private void fireDiconnected() {
final MudEvent e = new MudEvent(this);
this.events.dispatch(ConnectionListener.class, e,
ConnectionListener::disconnected);
}
public void addConnectionListener(ConnectionListener listener) {
this.events.addListener(ConnectionListener.class, listener);
}
public void removeConnectionListener(ConnectionListener listener) {
this.events.removeListener(ConnectionListener.class, listener);
}
@Override
public void close() throws IOException {
if (this.receiver != null) {
this.receiver.interrupt();
}
if (this.socket != null) {
this.socket.close();
}
this.in.close();
this.out.close();
}
}