package de.tud.kom.socom.components.game; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import de.tud.kom.socom.SocomComponent; import de.tud.kom.socom.GlobalConfig; import de.tud.kom.socom.database.game.GameDatabase; import de.tud.kom.socom.database.game.HSQLGameDatabase; import de.tud.kom.socom.util.SocomRequest; import de.tud.kom.socom.util.JSONUtils; import de.tud.kom.socom.util.ResourceLoader; import de.tud.kom.socom.util.exceptions.GameNotAuthenticatedException; import de.tud.kom.socom.util.exceptions.SocomException; import de.tud.kom.socom.util.exceptions.IllegalAccessException; import de.tud.kom.socom.util.media.MediaHandler; public class GameManager extends SocomComponent implements GlobalConfig { private static final String URL_PATTERN = "game"; private static GameManager instance = new GameManager(); private static GameDatabase db; private GameManager() { db = HSQLGameDatabase.getInstance(); } public static GameManager getInstance() { return instance; } /** * URL PATTERN IS "game" */ @Override public String getUrlPattern() { return URL_PATTERN; } /** * Create a new Game. * * Can be called without a user being logged in. * * @param game * The name of the new game * @param genre * @param password * @param mastersecret * @return error code * @throws SQLException * @throws JSONException */ public int addGame(SocomRequest req) throws SQLException, JSONException, SocomException { String name = req.getParam("game"); String genre = req.getParam("genre"); String password = req.getParam("password"); String mastersecret = req.getParam("mastersecret"); if (!mastersecret.equals(ResourceLoader.getResource("mastersecret"))) throw new IllegalAccessException(); Game game = new Game(-1L, name, genre, password, new ArrayList<GameInstance>()); db.addGame(game); req.addOutput(JSONUtils.getSuccessJsonString()); return 0; } /** * Remove a game. * * Can be called without a user being logged in. * * @param game * @param mastersecret * @return success boolean * @throws SQLException * @throws JSONException */ public int removeGame(SocomRequest req) throws SQLException, JSONException, SocomException { String mastersecret = req.getParam("mastersecret"); String game = req.getParam("game"); if (!mastersecret.equals(ResourceLoader.getResource("mastersecret"))) throw new IllegalAccessException(); db.removeGame(game); req.addOutput(JSONUtils.getSuccessJsonString()); return 0; } /** * Shows information about an existing game, including all instances. * * Can be called without a user being logged in. * * @param game * @param password * @return Game Object including its instances * @throws SQLException * @throws JSONException */ public int getGame(SocomRequest req) throws SQLException, JSONException, SocomException { String password = req.getParam("password"); String gamename = req.getParam("game"); long gameId = db.authenticateGame(gamename, password); Game game = db.getGame(gameId); if (game == null) throw new GameNotAuthenticatedException("Game not found"); req.addOutput(game.toJSONString()); return 0; } /** * Create a new Game Instance. * * Can be called without a user being logged in. * * @param game * @param password * @param version * (String) * @param description * @return success boolean * @throws SQLException * @throws JSONException */ public int addGameInstance(SocomRequest req) throws SQLException, JSONException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); String description = req.containsParam("description") ? req.getParam("description") : null; long gameId = db.authenticateGame(game, password); GameInstance gameinstance = new GameInstance(game, version, description); db.addInstance(gameId, gameinstance); req.addOutput(JSONUtils.getSuccessJsonString()); return 0; } /** * POST-Method (for longer description texts) * * Sets the description for a gameinstance * * @param game (cookie) * @param password (game's password) (cookie) * @param gameversion (gameversion since version is reserved cookie) (cookie) * @param description (as stream) * @return success boolean * @throws SQLException * @throws JSONException * @throws SocomException * @throws IOException */ public int setGameInstanceDescription(SocomRequest req) throws SQLException, JSONException, SocomException, IOException { String game = req.getCookieVal("game"); String password = req.getCookieVal("password"); String version = req.getCookieVal("gameversion"); BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream())); StringBuffer descriptionBuffer = new StringBuffer(); while(reader.ready()) { descriptionBuffer.append(reader.readLine()); } reader.close(); long gameInstance = db.authenticateGameInstance(game, version, password); boolean success = db.setInstanceDescription(gameInstance, descriptionBuffer.toString()); req.addOutput(JSONUtils.getSuccessJsonString(success)); return 0; } /** * Remove a game instance. Allows you to reuse the game+version combination. * * Can be called without a user being logged in. * * @param game * @param version * @param password * @return success boolean * @throws SQLException * @throws JSONException */ public int removeGameInstance(SocomRequest req) throws SQLException, JSONException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); long gameInstanceId = db.authenticateGameInstance(game, version, password); db.removeInstance(gameInstanceId); req.addOutput(JSONUtils.getSuccessJsonString()); return 0; } /** * Add a new Context to an existing GameInstance. * * Can be called without a user being logged in. * * @param game * @param version * @param password * @param contextid * Your external id * @param name * Context's name * @return success boolean * @throws JSONException * @throws SQLException */ public int addGameContext(SocomRequest req) throws JSONException, SQLException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); String extContextId = req.getParam("contextid"); String name = req.getParam("name"); long gameInstId = db.authenticateGameInstance(game, version, password); db.addContext(gameInstId, extContextId, name); req.addOutput(JSONUtils.getSuccessJsonString()); return 0; } /** * POST-Method * * sets the description of a given context * @param game (cookie) * @param password (game's password) (cookie) * @param gameversion (gameversion since version is reserved cookie) (cookie) (cookie) * @param contextid (cookie) * @param description (as stream) * @return success boolean * @throws JSONException * @throws SQLException * @throws SocomException * @throws IOException */ public int setGameContextDescription(SocomRequest req) throws JSONException, SQLException, SocomException, IOException { String game = req.getCookieVal("game"); String password = req.getCookieVal("password"); String version = req.getCookieVal("gameversion"); String contextid = req.getCookieVal("contextid"); long gameinstanceid = db.authenticateGameInstance(game, version, password); BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream())); StringBuffer descriptionBuffer = new StringBuffer(); while(reader.ready()) { descriptionBuffer.append(reader.readLine()); } reader.close(); boolean success = db.setContextDescription(gameinstanceid, contextid, descriptionBuffer.toString()); req.addOutput(JSONUtils.getSuccessJsonString(success)); return 0; } /** * Removes a contexts. * * Can be called without a user being logged in. * * @param game * @param version * @param password * @param contextid * @return success boolean * @throws JSONException * @throws SQLException */ public int removeGameContext(SocomRequest req) throws JSONException, SQLException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); String context = req.getParam("contextid"); long gameInstId = db.authenticateGameInstance(game, version, password); db.removeContext(gameInstId, context); req.addOutput(JSONUtils.getSuccessJsonString()); return 0; } /** * Retrieves all contexts from a gameintance including its scenes. * * Can be called without a user being logged in. * * @param game * @param version * @param password * @return error code * @throws JSONException * @throws SQLException */ public int getGameContexts(SocomRequest req) throws JSONException, SQLException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); long gameInstId = db.authenticateGameInstance(game, version, password); List<GameContext> result = db.getGameContexts(gameInstId); req.addOutput(JSONUtils.JSONToString(new JSONObject().put("contexts", result))); return 0; } /** * Retrieves the context with the given id. * * Can be called without a user being logged in. * * @param game * @param version * @param password * @param contextid * Your external id of the context which should be fetched * @return Game-Context Object * @throws SQLException * @throws JSONException */ public int getGameContext(SocomRequest req) throws SQLException, JSONException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); String contextid = req.getParam("contextid"); long gameinstid = db.authenticateGameInstance(game, version, password); GameContext gs = db.getGameContext(gameinstid, contextid); req.addOutput(JSONUtils.JSONToString(new JSONObject().put("context", gs))); return 0; } /** * Add a new relation between existing contexts. * * Can be called without a user being logged in. * * @param game * @param version * @param password * @param parent * External id of the parent-context-node * @param child * External id of the child-context-node * @return success boolean * @throws JSONException * @throws SQLException */ public int addGameContextRelation(SocomRequest req) throws JSONException, SQLException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); String parent = req.getParam("parent"); String child = req.getParam("child"); long gameInstId = db.authenticateGameInstance(game, version, password); db.addContextRelation(gameInstId, parent, child, false); req.addOutput(JSONUtils.getSuccessJsonString()); return 0; } /** * @see(addGameContextRelation) Removes relation between existing contexts. * * Can be called without a user being logged * in. * * @param game * @param version * @param password * @param parent * @param child * @return error code * @throws JSONException * @throws SQLException */ public int removeGameContextRelation(SocomRequest req) throws JSONException, SQLException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); String parent = req.getParam("parent"); String child = req.getParam("child"); long gameInstId = db.authenticateGameInstance(game, version, password); boolean success = db.removeContextRelation(gameInstId, parent, child); req.addOutput(JSONUtils.getSuccessJsonString(success)); return 0; } /** * Retrieves a context's relations from this gameintance. * GameContexts without any connections arent listed here * * Can be called without a user being logged in. * * @param game * @param version * @param password * @param contextid * @return List of Contexts containing the ids of their neighbour-nodes * @throws JSONException * @throws SQLException * @throws SocomException */ public int getGameContextRelations(SocomRequest req) throws JSONException, SQLException, SocomException { String password = req.getParam("password"); String game = req.getParam("game"); String version = req.getParam("version"); String contextid = req.getParam("contextid"); long gameInstId = db.authenticateGameInstance(game, version, password); GameContext result = db.getGameContextRelations(gameInstId, contextid); req.addOutput(JSONUtils.JSONToString(result.getJSONObject())); return 0; } /** * POST-METHOD Set the image for the given gameinstance which will represent * the game in the web-application * * Params must be given as cookies * * @param game * @param password * @param gameversion * (since version is reserved in cookies) * @param extension * Filename extension of the uploaded image file * @param The * Post-Stream should include the image (Good-Sizes: 460px × * 150px ~ 380px × 260px) * @return success boolean * @throws SocomException * @throws IOException * @throws JSONException * @throws SQLException */ public int setGameInstanceImage(SocomRequest req) throws SocomException, IOException, JSONException, SQLException { String password = req.getCookieVal("password"); String game = req.getCookieVal("game"); String version = req.getCookieVal("gameversion"); String extension = req.getCookieVal("extension"); InputStream imageStream = req.getInputStream(); long instanceid = db.authenticateGameInstance(game, version, password); String imageFile = MediaHandler.saveGameImage(game, version, extension, imageStream); boolean success = db.setInstanceImage(instanceid, imageFile); req.addOutput(JSONUtils.getSuccessJsonString(success)); return 0; } /** * POST-METHOD Set the image for the given gamecontext in the given * gameinstance which will represent the context in the web-application * * Params must be given as cookies * * @param game * @param password * @param gameversion * (since version is reserved in cookies) * @param contextid * @param extension * Filename extension of the uploaded image file * @param The * Post-Stream should include the image (Good-Sizes: 460px × * 150px ~ 380px × 260px) * @return success boolean * @throws SocomException * @throws IOException * @throws JSONException * @throws SQLException */ public int setGameContextImage(SocomRequest req) throws SocomException, IOException, SQLException, JSONException { String password = req.getCookieVal("password"); String game = req.getCookieVal("game"); String version = req.getCookieVal("gameversion"); String contextid = req.getCookieVal("contextid"); String extension = req.getCookieVal("extension"); InputStream imageStream = req.getInputStream(); long instanceid = db.authenticateGameInstance(game, version, password); String imageFile = MediaHandler.saveContextImage(game, version, contextid, extension, imageStream); boolean success = db.setContextImage(instanceid, contextid, imageFile); req.addOutput(JSONUtils.getSuccessJsonString(success)); return 0; } }