import java.awt.*; import java.io.*; import java.net.*; import java.util.*; class GameClient extends Object implements Runnable { public final static int DEFAULT_PORT = 7779; boolean readerProcess = false; boolean connected = false; InetAddress inetHost; int port; Socket connection; DataInputStream dataIn; PrintStream dataOut; Thread readerProc; Thread writerProc; Thread parserProc; GameWindow gw = null; GameControl gc = null; String playerName = null; Vector Messages = new Vector(); Vector Outgoing = new Vector(); riskaplt risk; // JavaChat jc; GameClient(String host, int Port, String Name, riskaplt r) { risk = r; playerName = Name; if(Port == 0) Port = DEFAULT_PORT; port = Port; try { inetHost = InetAddress.getByName(host); } catch (Exception e) { System.err.println("GameClient: Unknown host "+host); //System.exit(1); return; } boolean retry = true; boolean triedstart = false; while (retry) { try { retry = false; connection = new Socket(inetHost, port); if(triedstart) System.out.println("Server restarted successfully!"); } catch (Exception e) { if(!triedstart) { StartServer.startServer("http://cs.millersv.edu/~atgraham/java/game/client/startserver.cgi"); triedstart = true; retry = true; } else { System.err.println("GameClient: Could not connect to "+host+" "+port); //System.exit(1); return; } } } System.out.println("GameServer: Connected..."); connected = true; boolean autoflush = true; try { dataIn = new DataInputStream(connection.getInputStream()); dataOut = new PrintStream(connection.getOutputStream(),autoflush); } catch (Exception e) { closeConnection(); System.err.println("Error getting socket streams. "+e); return; } writerProc = new Thread(this,"W"); readerProc = new Thread(this,"R"); parserProc = new Thread(this,"P"); writerProc.setPriority(Thread.NORM_PRIORITY); readerProc.setPriority(Thread.NORM_PRIORITY); parserProc.setPriority(Thread.NORM_PRIORITY + 1); writerProc.start(); readerProc.start(); parserProc.start(); if(gw == null) gw = new GameWindow(this); if(gc == null) gc = new GameControl(risk); risk.setGameControl(gc); } public void closeConnection() { if(gw != null) { gw.hide(); gw.dispose(); gw = null; } if(gc != null) { gc.hide(); gc.destroy(); gc = null; } System.out.println("****** Connection Closed ******"); readerProc.stop(); writerProc.stop(); parserProc.stop(); connected = false; Thread.dumpStack(); if(Thread.currentThread() != null) System.out.println("CT = "+Thread.currentThread().toString()); try { connection.close(); } catch(Exception e2) { } //System.exit(0); } public void sendMessage(String msg) { // System.out.println("W"+Outgoing.size()+"("+msg+")"); Outgoing.addElement(msg); } public void writer() { int errs = 0; String msg; System.out.println("** Starting Writer **"); while(connected) { try { while(Outgoing.size() == 0) writerProc.sleep(10); msg = (String) Outgoing.firstElement(); Outgoing.removeElement(msg); if(msg != null) { // System.out.println(">> "+msg); dataOut.println(msg); } } catch (Exception e) { System.out.println("#W# "+errs+" "+e); errs++; try { writerProc.sleep(200); } catch(Exception e2) { } } } } public String getMessage() { String message; if(Messages.size() == 0) return null; message = (String) Messages.firstElement(); Messages.removeElement(message); // System.out.println("<< "+message); return message; } public boolean msgAvailable() { return Messages.size() != 0; } public void run() { String threadName = Thread.currentThread().getName(); if(threadName.equals("R")) reader(); else if(threadName.equals("W")) writer(); else if(threadName.equals("P")) parser(); else System.err.println("!! GameClient::run() : Unknown thread name"); } public void reader() { String msg = null; int errs = 0; System.out.println("** Starting Reader **"); while(connected) { try { while(dataIn.available() == 0) readerProc.sleep(10); msg = dataIn.readLine(); } catch(Exception e) { System.out.println("#R# "+errs+" "+e); errs++; msg = null; try { readerProc.sleep(200); } catch(Exception e2) { } } // System.out.println("R"+Messages.size()+"("+msg+")"); Messages.addElement(msg); } } public void parser() { System.out.println("** Starting Parser **"); boolean connected = true; while(connected) { try { while(!msgAvailable()) parserProc.sleep(20); String data = getMessage(); System.out.println("P:"+data); connected = parse(data); } catch (Exception e) { e.printStackTrace(); } } closeConnection(); } boolean saidHello = false; private boolean parse(String data) { //System.out.println("#|"+data+"|"); if(data == null) return false; StringTokenizer tokenFactory = new StringTokenizer(data,"\t\n\r"); int numTokens = tokenFactory.countTokens(); if(numTokens == 0) return true; if(!saidHello) { if(numTokens == 2 && tokenFactory.nextToken().equals(risk.PROTOCOL)) { risk.playerID = tokenFactory.nextToken(); sendMessage(risk.PROTOCOL+"\t"+risk.GAMETYPE+"\t"+playerName); saidHello = true; sendMessage("LIST\tGAMES"); // get a list of games sendMessage("LIST\tPLAYERS"); // get list of players return true; } return false; } else { String cmd = tokenFactory.nextToken(); if(cmd.equals("TOALL") || cmd.equals("TOMASTER") || cmd.equals("FROMMASTER")) { risk.riskparse(data); return true; } if(numTokens == 1) { if(cmd.equals("BYE!")) { return false; } if(cmd.equals("STARTGAME")) { if(gc != null) { gc.destroy(); gc = null; } risk.startRisk(); return true; } } else if(numTokens == 2) { String tok2 = tokenFactory.nextToken(); if(cmd.equals("GAMEOVER")) { displayMessage(null,risk.getGameName(tok2)+" has ended."); if(risk.gameID.equals(tok2)) { sendMessage("JOIN\t0"); if(gc == null) gc = new GameControl(risk); risk.gameOver(); } return true; } if(cmd.equals("DESTROYED")) { displayMessage(null,risk.getGameName(tok2)+" was disbanded."); risk.removeGame(tok2); sendMessage("LIST\tPLAYERS"); return true; } if(cmd.equals("PLAYERLEFT")) { iPlayer p = risk.findPlayer(tok2); if(p != null) risk.remove(p); sendMessage("LIST\tPLAYERS"); } } else if(numTokens == 3) { String tok2 = tokenFactory.nextToken(); String tok3 = tokenFactory.nextToken(); if(cmd.equals("MSG")) { displayMessage(tok2,tok3); } if(cmd.equals("JOINED")) { if(tok2.equals(risk.playerID)) { risk.gameID = tok3; displayMessage(null,"Joined "+risk.getGameName(risk.gameID)); } else { if(tok3.equals(risk.gameID)) { displayMessage(null,risk.getPlayerName(tok2)+" has joined this game."); } } risk.updatePlayer(tok2,tok3); return true; } if(cmd.equals("PLAYERQUIT")) { sendMessage("LIST\tPLAYERS"); displayMessage(null,risk.getPlayerName(tok2)+" left this game."); return true; } } else if(numTokens == 4) { String pid = tokenFactory.nextToken(); String name = tokenFactory.nextToken(); String gid = tokenFactory.nextToken(); if(cmd.equals("PLAYER")) { risk.updatePlayer(pid,name,gid); return true; } } else if(numTokens == 5) { } else if(numTokens == 6) { } else if(numTokens == 7) { String type = tokenFactory.nextToken(); String gid = tokenFactory.nextToken(); String maxplayers = tokenFactory.nextToken(); String started = tokenFactory.nextToken(); String name = tokenFactory.nextToken(); String owner = tokenFactory.nextToken(); if(cmd.equals("GAME") || cmd.equals("CREATED")) { risk.updateGame(type, gid, maxplayers, started, name, owner); return true; } } } return true; } public void displayMessage(String n, String msg) { if(n == null) n = "-----> "; else n += " : "; gw.displayMessage(n+msg); } }