Per il mio semplice client MUD sto usando Apache Telnet (no, non ssh). Un cliente di fango è una strana bestia:
Generally, a MUD client is a very basic telnet client that lacks VT100 terminal emulation and the capability to perform telnet negotiations. ... Standard features seen in most MUD clients include ANSI color support, aliases, triggers and scripting. - Wikipedia
Vorrei come per un Controller
non ancora scritto per avere un riferimento a TelnetConnection
e usarlo solo per un livello più alto di astrazione per I / O, ma tutti i tentativi di premio questa classe a parte non riescono per me. TelnetConnection
sembra assumersi la responsabilità per tutto, e poi alcuni, e continua a crescere.
package telnet;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Deque;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Logger;
import org.apache.commons.net.telnet.TelnetClient;
import player.GameAction;
import player.DataFromRegex;
import player.Regex;
public class TelnetConnection implements Observer {
private static Logger log = Logger.getLogger(TelnetConnection.class.getName());
private TelnetClient telnetClient = new TelnetClient();
private InputOutput inputOutput = new InputOutput();
private Regex regexParser = new Regex();
private DataFromRegex data = null;
private Logic logic = new Logic();
public TelnetConnection() {
init();
}
private void init() {
try {
int port = 3000;
InetAddress host = InetAddress.getByName("rainmaker.wunderground.com");
telnetClient.connect(host, port);
inputOutput.readWriteParse(telnetClient.getInputStream(), telnetClient.getOutputStream());
} catch (SocketException ex) {
} catch (IOException ex) {
}
inputOutput.addObserver(this);
}
private void sendAction(GameAction action) throws IOException {
log.info(action.toString());
byte[] actionBytes = action.getAction().getBytes();
OutputStream outputStream = telnetClient.getOutputStream();
outputStream.write(actionBytes);
outputStream.write(13);
outputStream.write(10);
outputStream.flush();
}
private void sendActions(Deque<GameAction> gameActions) {
while (!gameActions.isEmpty()) {
GameAction action = gameActions.remove();
try {
sendAction(action);
} catch (IOException ex) {
}
}
}
@Override
public void update(Observable o, Object arg) {
String line = null;
if (o instanceof InputOutput) {
line = inputOutput.getLine();
log.fine(line);
data = regexParser.parse(line);
Deque<GameAction> gameActions = logic.getActions(data);
sendActions(gameActions);
}
}
public static void main(String[] args) {
new TelnetConnection();
}
}
Parte della difficoltà si trova nella classe InputOutput
, che è adattata da IOUtil
da Apache. (Per qualche ragione, non posso includere il link al codice sorgente di Apache.)
Una volta inviato il InputStream
a InputOutput
, è necessario richiamare utilizzando Observable
per poi inviare i dati di stringa per la corrispondenza e la ricerca? E poi torna cosa dopo aver trovato e cercato il testo?
Il trucco è, in termini di I / O:
- input della console di acquisizione
- stampa l'output remoto dal server MUD alla console come un normale telnet
- un po 'di regex / etc sull'output remoto, concomitante con flussi aperti non terminati.
Quest'ultima esigenza sembra creare una strana bestia per la quale non posso prevedere il flusso di controllo e dati.