package dk.socketmud.io; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.Iterator; import dk.socketmud.action.CommandSet; import dk.socketmud.object.Character; import dk.socketmud.util.Log; public class SMServer { protected ServerSocket control; protected ArrayList<SMClient> clients; public SMServer(int port) throws IOException, IllegalArgumentException { control = new ServerSocket(port); clients = new ArrayList<SMClient>(); control.setSoTimeout(50); Log.logString("Accepting connections on port " + port); } public SMClient acceptNewConnections() throws IOException { SMClient client; try { Socket s = control.accept(); client = new SMClient(this, s); clients.add(client); } catch (SocketTimeoutException ex) { return null; } return client; } public void flush() { Iterator<SMClient> i = clients.iterator(); while (i.hasNext()) { SMClient client = null; try { client = i.next(); client.flush(); } catch (IOException ex) { Log.logString("Failed to flush client. Closing connection"); i.remove(); if (client != null) { try { client.close(); } catch (IOException e) { Log.logString("Failed to close connection"); } } } } } public ArrayList<CommandSet> readCommands() { ArrayList<CommandSet> cmds = new ArrayList<CommandSet>(); Iterator<SMClient> i = clients.iterator(); while (i.hasNext()) { SMClient client = null; try { String command; String argument = ""; client = i.next(); client.read(); int index = client.inBuffer.indexOf(' '); if (index > -1) { command = client.inBuffer.substring(0, index); argument = client.inBuffer.substring(index + 1); } else command = client.inBuffer; if (client.inBuffer != null) { if (client.state.equals(SMClient.State.Connected)) { if ((command = client.ch.canInterpret(command)) != null) { CommandSet cmd = new CommandSet(client.ch, argument, command); cmds.add(cmd); } else client.ch.writeDuh(); break; } else if (client.state.equals(SMClient.State.PromptName)) { client.nameBuffer = command; client.write("Are you sure you want to be known as " + client.nameBuffer + " [Y/N]? "); client.state = SMClient.State.PromptNameVerify; } else if (client.state.equals(SMClient.State.PromptNameVerify)) { if (command.equalsIgnoreCase("Y") || command.equalsIgnoreCase("YES")) { client.ch = new Character(client, client.nameBuffer); client.state = SMClient.State.Connected; client.write("Welcome to SocketMUD " + client.ch.getName() + "\r\n"); } else if (command.equalsIgnoreCase("N") || command.equalsIgnoreCase("NO")) { client.write("Then what name do you want? "); client.state = SMClient.State.PromptName; } else { client.write("What is it, (Y)es or (N)o? "); } } else { Log.logString("Client in unknown state: " + client.state.toString()); throw new IOException(); } } } catch (SocketTimeoutException ex) { ; // not a problem } catch (IOException ex) { Log.logString("IOException on client. Closing connection"); i.remove(); if (client != null) { try { client.close(); } catch (IOException e) { Log.logString("Failed to close connection"); } } } } return cmds; } }