import java.io.*; import java.net.*; import java.util.*; public class Player extends Thread { private Connection conn = null; private String name = ""; private FortSrv server = null; private boolean isconnected = false; private boolean isplaying = false; private ArrayList hand; private ArrayList city; private int gold; private String checkConnect( String s ) { String playername = null; if (s != null) { if (s.startsWith( "connect fortresses" )) { int major = server.majversion; int minor = server.minversion; int rmajor; int rminor; String rname; MyStringTokenizer st = new MyStringTokenizer( s ); st.nextToken(); st.nextToken(); rmajor = Integer.parseInt( st.nextToken() ); rminor = Integer.parseInt( st.nextToken() ); st.nextToken(); rname = (st.rest()).replaceAll( "\\W", "_" ); if (rmajor >= major && rminor >= minor) { playername = rname; } } } return playername; } public Player( Connection connection, FortSrv srv, int idx, Vector startinghand ) { super( "Player " + idx ); conn = connection; server = srv; hand = new ArrayList( startinghand ); city = new ArrayList(); gold = 2; } public void talk( String from, boolean broadcast, String message ) { conn.sendln( "talk:" + from + ":" + broadcast + ":" + message ); } public void sendMessage( FMessage msg ) { conn.sendln( msg.toString() ); } public void run() { String instr; boolean drop = false; String msgheader = ""; try { conn.sendln( "Welcome to " + server.serverInfo() ); instr = checkConnect( conn.readln() ); if (instr == null) { System.out.println( getName() + " not using correct protocol. " + "Disconnecting." ); drop = true; } else { System.out.println( "Player '" + getName() + "' connected." ); conn.sendln( "Ok." ); isconnected = true; try { String oldname = getName(); setName( instr ); System.out.println( "'" + oldname + "' changed name to '" + getName() + "'." ); } catch (SecurityException e) { System.out.println( "Unable to change name '" + getName() + "' to '" + instr + "'" ); } conn.sendln( getName() + " connected." ); conn.sendln( "Send 'help' for help." ); prompt(); } } catch (IOException e) { drop = true; System.out.println( "Unable to establish connection with player.\n" + "Reason: " + e.getMessage() ); } try { if (!drop) { while ((instr = conn.readln()) != null) { StringTokenizer st = new StringTokenizer( instr ); msgheader = st.nextToken(); if (msgheader.equals( "rename" )) { } else if (msgheader.equals( "say" ) || msgheader.equals( "shout" )) { FMessage msg = FMessage.createMessage( instr, getName() ); if (! server.sendMessage( msg )) { if (! server.playerExists( msg.playerto )) { conn.sendln( "Could not send message. No such player " + msg.playerto + "." ); } else { try { conn.sendln( "Could not send message to " + server.getPlayerName( msg.playerto ) + "." ); } catch (Exception e) { // syncro error? seems unlikely, but meh. not serious, anyway. conn.sendln( "Could not send message to player " + msg.playerto + "." ); } } } } else if (msgheader.equals( "action" ) || msgheader.equals( "income" ) || msgheader.equals( "special" ) || msgheader.equals( "build" ) || msgheader.equals( "district" ) || msgheader.equals( "endturn" )) { } else if (msgheader.equals( "selectrole" ) || msgheader.equals( "discardrole" )) { } else if (msgheader.equals( "status" )) { if (st.hasMoreTokens()) { conn.sendln( server.playerStatus( Integer.parseInt( st.nextToken() ) ) ); } else { conn.sendln( getExtendedStatus() ); } } else if (msgheader.equals( "players" )) { } else if (msgheader.equals( "help" )) { if (st.hasMoreTokens()) { conn.sendln( server.protocolHelp( st.nextToken() ) ); } else { conn.sendln( server.protocolHelp( "help" ) ); } } else if (msgheader.equals( "serverinfo" )) { conn.sendln( server.serverInfo() ); } else if (msgheader.equals( "q" ) || msgheader.equals( "quit" )) { drop = true; conn.sendln( "Goodbye." ); System.out.println( getName() + " disconnected." ); } else { conn.sendln( "Command '" + msgheader + "' not recognized." ); } if (drop) { break; } prompt(); } } } catch (IOException e) { System.out.println( "Connection error talking to '" + getName() + "'.\n" + "Reason: " + e.getMessage() ); } conn.close(); } public String getStatus() { String s = "Name: " + getName() + "\n" + "Gold: " + getGold() + "\n" + "Hand: (" + hand.size() + " cards)\n" + "City:\n" + getDistrictDetails( city ) + server.playerFlags( getIndex() ); return s; } private String getDistrictDetails( ArrayList list ) { StringBuilder s = new StringBuilder(); if (list.isEmpty()) { s.append( " (no cards)\n" ); } else { for (District d : hand) { s.append( " " + d.toString() + "\n" ); } } return s.toString(); } private String getExtendedStatus() { String s = "Player index: " + getIndex() + "\n" + "Name: " + getName() + "\n" + "Gold: " + getGold() + "\n" + "Hand:\n" + getDistrictDetails( hand ) + "City:\n" + getDistrictDetails( city ) + server.playerFlags( getIndex() ); return s; } public boolean connected() { return isconnected; } public int getGold() { return gold; } public int addGold( int g ) { gold += g; return gold; } public int removeGold( int g ) { gold -= g; return gold; } public int stealGold() { int g = gold; gold = 0; return g; } public int getIndex() { return server.getIndex( this ); } public boolean playing() { return isplaying; } public synchronized void setPlaying( boolean p ) { isplaying = p; } private void prompt() { conn.send( "> " ); } }