package com.charlesmadere.android.classygames.server; import android.util.Log; import com.charlesmadere.android.classygames.utilities.Utilities; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.HTTP; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /** * Class for tons of stuff relating to communication with the Classy Games * server. */ public final class Server { public final static String LOG_TAG = Utilities.LOG_TAG + " - Server"; public final static long WAIT_FOR_SERVER_DELAY = 1000l; private final static String ADDRESS_MAIN = "http://classygames.elasticbeanstalk.com/"; private final static String ADDRESS_FORFEIT_GAME = ADDRESS_MAIN + "ForfeitGame"; private final static String ADDRESS_GET_GAME = ADDRESS_MAIN + "GetGame"; private final static String ADDRESS_GET_GAMES = ADDRESS_MAIN + "GetGames"; private final static String ADDRESS_GET_STATS = ADDRESS_MAIN + "GetStats"; private final static String ADDRESS_NEW_GAME = ADDRESS_MAIN + "NewGame"; private final static String ADDRESS_NEW_MOVE = ADDRESS_MAIN + "NewMove"; private final static String ADDRESS_NEW_REG_ID = ADDRESS_MAIN + "NewRegId"; private final static String ADDRESS_REMOVE_REG_ID = ADDRESS_MAIN + "RemoveRegId"; private final static String ADDRESS_SKIP_MOVE = ADDRESS_MAIN + "SkipMove"; public final static String POST_DATA = "json"; public final static String POST_DATA_BOARD = "board"; public final static String POST_DATA_CHECKERS = "checkers"; public final static String POST_DATA_CHESS = "chess"; public final static String POST_DATA_ERROR = "error"; public final static String POST_DATA_FINISHED = "finished"; public final static String POST_DATA_GAME_ID = "game_id"; public final static String POST_DATA_GAME_TYPE = "game_type"; public final static byte POST_DATA_GAME_TYPE_CHECKERS = 1; public final static byte POST_DATA_GAME_TYPE_CHESS = 2; public final static String POST_DATA_ID = "id"; public final static String POST_DATA_LAST_MOVE = "last_move"; public final static String POST_DATA_LOSES = "loses"; public final static String POST_DATA_MESSAGE_TYPE = "message_type"; public final static byte POST_DATA_MESSAGE_TYPE_NEW_GAME = 1; public final static byte POST_DATA_MESSAGE_TYPE_NEW_MOVE = 2; public final static byte POST_DATA_MESSAGE_TYPE_GAME_OVER_LOSE = 7; public final static byte POST_DATA_MESSAGE_TYPE_GAME_OVER_WIN = 15; public final static String POST_DATA_NAME = "name"; public final static String POST_DATA_REG_ID = "reg_id"; public final static String POST_DATA_RESULT = "result"; public final static String POST_DATA_TURN = "turn"; public final static String POST_DATA_TURN_THEIRS = "turn_theirs"; public final static String POST_DATA_TURN_YOURS = "turn_yours"; public final static String POST_DATA_SUCCESS = "success"; public final static String POST_DATA_USER_CHALLENGED = "user_challenged"; public final static String POST_DATA_USER_CREATOR = "user_creator"; public final static String POST_DATA_WINS = "wins"; /** * Makes an HTTP POST request to the Classy Games server on the ForfeitGame * end point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerForfeitGame(final ApiData data) throws IOException { return postToServer(ADDRESS_FORFEIT_GAME, data); } /** * Makes an HTTP POST request to the Classy Games server on the GetGame end * point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerGetGame(final ApiData data) throws IOException { return postToServer(ADDRESS_GET_GAME, data); } /** * Makes an HTTP POST request to the Classy Games server on the GetGames * end point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerGetGames(final ApiData data) throws IOException { return postToServer(ADDRESS_GET_GAMES, data); } /** * Makes an HTTP POST request to the Classy Games server on the GetStats * end point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerGetStats(final ApiData data) throws IOException { return postToServer(ADDRESS_GET_STATS, data); } /** * Makes an HTTP POST request to the Classy Games server on the NewGame end * point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerNewGame(final ApiData data) throws IOException { return postToServer(ADDRESS_NEW_GAME, data); } /** * Makes an HTTP POST request to the Classy Games server on the NewMove end * point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerNewMove(final ApiData data) throws IOException { return postToServer(ADDRESS_NEW_MOVE, data); } /** * Makes an HTTP POST request to the Classy Games server on the NewRegId * end point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerNewRegId(final ApiData data) throws IOException { return postToServer(ADDRESS_NEW_REG_ID, data); } /** * Makes an HTTP POST request to the Classy Games server on the RemoveRegId * end point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerRemoveRegId(final ApiData data) throws IOException { return postToServer(ADDRESS_REMOVE_REG_ID, data); } /** * Makes an HTTP POST request to the Classy Games server on the SkipMove * end point. * * @param data * A list of key-value pairs to be sent to the server. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ public static String postToServerSkipMove(final ApiData data) throws IOException { return postToServer(ADDRESS_SKIP_MOVE, data); } /** * Use this method to send data to and receive a response from the server. * The String that this method returns is the server's response. * * @param url * The URL that you want to send your data to. This should be formulated * using the URLs found in this class. * * @param data * Data to be sent to the server using HTTP POST. * * @return * The server's response as a String. This will need to be parsed as it is * JSON data. <strong>There is a slight possibility that the data String * returned from this method will be null.</strong> Please check for that * <strong>as well as</strong> if the String is empty. * * @throws IOException * If something weird happens when trying to POST to the server then this * exception will be thrown. */ private static String postToServer(final String url, final ApiData data) throws IOException { String serverResponse = null; Log.d(LOG_TAG, "Posting data to server at " + url); final HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(data.getKeyValuePairs())); final HttpClient httpClient = new DefaultHttpClient(); final HttpResponse httpResponse = httpClient.execute(httpPost); final InputStream inputStream = httpResponse.getEntity().getContent(); if (inputStream != null) { final InputStreamReader inputStreamReader = new InputStreamReader(inputStream, HTTP.UTF_8); final BufferedReader bufferedReader = new BufferedReader(inputStreamReader); final StringBuilder stringBuilder = new StringBuilder(); String line = ""; while (line != null) { stringBuilder.append(line); line = bufferedReader.readLine(); } serverResponse = stringBuilder.toString(); } return serverResponse; } /** * Ensures that a gameType byte received from the server is a valid * gameType byte. * * @param gameType * The gameType byte to check for validity. * * @return * Returns true if the given gameType byte is valid. */ public static boolean validGameTypeValue(final byte gameType) { switch (gameType) { case POST_DATA_GAME_TYPE_CHECKERS: case POST_DATA_GAME_TYPE_CHESS: return true; default: return false; } } /** * Ensures that a messageType byte received from the server is a valid * messageType byte. * * @param messageType * The messageType byte to check for validity. * * @return * Returns true if the given messageType byte is valid. */ public static boolean validMessageTypeValue(final byte messageType) { switch (messageType) { case POST_DATA_MESSAGE_TYPE_NEW_GAME: case POST_DATA_MESSAGE_TYPE_NEW_MOVE: case POST_DATA_MESSAGE_TYPE_GAME_OVER_LOSE: case POST_DATA_MESSAGE_TYPE_GAME_OVER_WIN: return true; default: return false; } } /** * Ensures that a winOrLose byte received from the server is a valid * winOrLose byte. * * @param winOrLose * The winOrLose byte to check for validity. * * @return * Returns true if the given winOrLose byte is valid. */ public static boolean validWinOrLoseValue(final byte winOrLose) { switch (winOrLose) { case POST_DATA_MESSAGE_TYPE_GAME_OVER_LOSE: case POST_DATA_MESSAGE_TYPE_GAME_OVER_WIN: return true; default: return false; } } }