package player; import edu.neu.ccs.demeterf.http.classes.*; import edu.neu.ccs.demeterf.http.server.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import logging.Logger; import scg.Util; import scg.gen.PlayerContext; import edu.neu.ccs.demeterf.lib.*; import hidden.Tools; /** Server class for the player. Dispatches to HTTP methods with context. */ @Server public class PlayerServer { /** Path the player server listens for */ public static final String EntryPath = "/player"; /** Receives a competition "start" message at this path */ public static final String StartPath = "/start"; /** Receives a competition "end" message at this path */ public static final String EndPath = "/end"; /** Default port for the Player */ public static final int DEFAULT_PORT = 8000; /** Port number for this player instance */ @Port protected final int port; /** logger instance for the player */ private final Logger log; /** * A Factory for Player instances to allow different (special) players to be * created, triggered by command line arguments */ private final PlayerFactory factory; public PlayerServer(PlayerFactory fact, Logger l) { this(fact, DEFAULT_PORT, l); } public PlayerServer(PlayerFactory fact, int p, Logger l) { factory = fact; port = p; log = l; } /** Handle an Admin request at the EntryPath */ @Path(EntryPath) public HTTPResp playerResponse(HTTPReq req){ try { long turnStart = System.currentTimeMillis(); // Get the player context from the body of the request PlayerContext pContext = PlayerContext.parse(req.getBodyString()); // Run the Player HTTPResp resp = createResponse(pContext); log.notify("Turn Completed: "+Util.format((System.currentTimeMillis()-turnStart)/1000.0)+" sec"); return resp; } catch (Exception e) { // Error Creating the Player's Context log.error("Exception: " + e.getMessage()); log.error("StackTrace:"); for(StackTraceElement se : Util.rootCause(e).getStackTrace()) log.notify(se.toString()); return HTTPResp.textError("" + e); } } /** Handle an Admin competition "start" message */ @Path(StartPath) public HTTPResp startResponse(HTTPReq req){ return HTTPResp.textResponse("OK"); } /** Handle an Admin competition "end" message */ @Path(EndPath) public HTTPResp endResponse(HTTPReq req){ return HTTPResp.textResponse("OK"); } /** Default Handler for other paths */ @Path public HTTPResp defaultResponse(){ return HTTPResp.textError("Unknown Request"); } /** Formulate a player response for a given PlyerContext */ public HTTPResp createResponse(PlayerContext ctx){ return HTTPResp.textResponse(factory.getAPlayer(ctx, log).playString()); } /** Clear message for Linux terminals */ static String clearer = List.create(0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, 0x00).map( new List.Map() { public Character map(Integer i) { return (char) (int) i; } }).toString("", ""); /** Main method to run the PlayerServer. Will be called by Player Main. */ public static void run(PlayerFactory fact, int port, Logger log) throws IOException{ // Create a new Server ServerThread server = Factory.create(new PlayerServer(fact, port, log)); // Buffer text from the terminal BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); String inpt = ""; do { System.out.print("\n ** Type 'exit' to shutdown: "); System.out.flush(); inpt = input.readLine().trim(); // Respond to (limited) input commands if (inpt.equals("clear"))System.err.print(clearer); if (inpt.equals("finalprefs"))Tools.printPrefs(); } while (!inpt.equals("exit")); log.event("Shutting down Player Server"); // Kill the PlayerServer thread server.shutdown(); } }