/** * Creates a character for a account of a player * * @param username player's username * @param character * @param template the template we are going to use to create the object. * @param address ip address of client * @return a Result indicating if account creation was done successfully or if it is not the * cause. */ public CharacterResult createCharacter( String username, String character, RPObject template, String address) { try { if (!Boolean.parseBoolean( Configuration.getConfiguration().get("allow_account_creation", "true"))) { return new CharacterResult(Result.FAILED_CREATE_ON_MAIN_INSTEAD, character, template); } } catch (IOException e) { logger.error(e, e); } // check account creation limits try { if (DAORegister.get() .get(CharacterDAO.class) .isCharacterCreationLimitReached(username, address)) { return new CharacterResult(Result.FAILED_TOO_MANY, character, template); } } catch (SQLException e) { logger.error(e, e); return new CharacterResult(Result.FAILED_EXCEPTION, character, template); } catch (IOException e) { logger.error(e, e); return new CharacterResult(Result.FAILED_EXCEPTION, character, template); } return ruleProcessor.createCharacter(username, character, template); }
/** This method is called when connection to client is closed */ public void onTimeout(RPObject object) throws RPObjectNotFoundException { DebugInterface.get().onTimeout(object); scheduler.clearRPActions(object); contentsToTransfer.remove(object); ruleProcessor.onTimeout(object); }
/** * Creates an account for a player in the game. * * @param username player's username * @param password player's password * @param email player's email * @param address ip address of client * @return a Result indicating if account creation was done successfully or not. */ public AccountResult createAccount( String username, String password, String email, String address) { try { if (!Boolean.parseBoolean( Configuration.getConfiguration().get("allow_account_creation", "true"))) { return new AccountResult(Result.FAILED_CREATE_ON_MAIN_INSTEAD, username); } } catch (IOException e) { logger.error(e, e); } // check account creation limits try { if (DAORegister.get().get(AccountDAO.class).isAccountCreationLimitReached(address)) { return new AccountResult(Result.FAILED_TOO_MANY, username); } } catch (SQLException e) { logger.error(e, e); return new AccountResult(Result.FAILED_EXCEPTION, username); } catch (IOException e) { logger.error(e, e); return new AccountResult(Result.FAILED_EXCEPTION, username); } // forward the creation request to the game return ruleProcessor.createAccount(username, password, email); }
/** * This method is called when a player leaves the game * * @param object player object * @return true, to continue, false to prevent logout */ public boolean onExit(RPObject object) throws RPObjectNotFoundException { scheduler.clearRPActions(object); contentsToTransfer.remove(object); if (!DebugInterface.get().onExit(object)) { return false; } return ruleProcessor.onExit(object); }
/** * This method loads the extensions: IRPRuleProcessor and IRPWorld that are going to be used to * implement your game. This method loads these class from the class names passed as arguments in * Configuration * * @param conf the Configuration class * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalAccessException * @throws SecurityException * @throws IllegalArgumentException */ protected void initializeExtensions(Configuration conf) throws ClassNotFoundException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { Class<?> worldClass = Class.forName(conf.get("world", "marauroa.server.game.rp.RPWorld")); // call the get() method without parameters to retrieve the singleton // instance world = (RPWorld) worldClass.getDeclaredMethod("get", new Class[0]).invoke(null, (Object[]) null); RPWorld.set(world); world.onInit(); Class<?> ruleProcessorClass = Class.forName(conf.get("ruleprocessor", "marauroa.server.game.rp.RPRuleProcessorImpl")); // call the get() method without parameters to retrieve the singleton // instance ruleProcessor = (IRPRuleProcessor) ruleProcessorClass.getDeclaredMethod("get", new Class[0]).invoke(null, (Object[]) null); ruleProcessor.setContext(this); }
/** * gets an input stream to the requested resource * * @param resource name of resource * @return InputStream or <code>null</code> */ public InputStream getResource(String resource) { return ruleProcessor.getResource(resource); }
/** * gets the content type for the requested resource * * @param resource name of resource * @return mime content/type or <code>null</code> */ public String getMimeTypeForResource(String resource) { return ruleProcessor.getMimeTypeForResource(resource); }
@Override public void run() { try { long start = System.nanoTime(); long stop; long delay; long timeStart = 0; long[] timeEnds = new long[12]; while (keepRunning) { stop = System.nanoTime(); logger.debug("Turn time elapsed: " + ((stop - start) / 1000) + " microsecs"); delay = turnDuration - ((stop - start) / 1000000); if (delay < 0) { StringBuilder sb = new StringBuilder(); for (long timeEnd : timeEnds) { sb.append(" " + (timeEnd - timeStart)); } logger.warn("Turn duration overflow by " + (-delay) + " ms: " + sb.toString()); } else if (delay > turnDuration) { logger.error( "Delay bigger than Turn duration. [delay: " + delay + "] [turnDuration:" + turnDuration + "]"); delay = 0; } // only sleep when the turn delay is > 0 if (delay > 0) { try { Thread.sleep(delay); } catch (InterruptedException e) { // ignore } } start = System.nanoTime(); timeStart = System.currentTimeMillis(); playerContainer.getLock().requestWriteLock(); try { timeEnds[0] = System.currentTimeMillis(); /* Get actions that players send */ scheduler.nextTurn(); timeEnds[1] = System.currentTimeMillis(); /* Execute them all */ scheduler.visit(ruleProcessor); timeEnds[2] = System.currentTimeMillis(); /* Compute game RP rules to move to the next turn */ ruleProcessor.endTurn(); timeEnds[3] = System.currentTimeMillis(); /* Send content that is waiting to players */ deliverTransferContent(); timeEnds[4] = System.currentTimeMillis(); /* Tell player what happened */ buildPerceptions(); timeEnds[5] = System.currentTimeMillis(); /* save players regularly to the db */ savePlayersPeriodicly(); timeEnds[6] = System.currentTimeMillis(); /* Move zone to the next turn */ world.nextTurn(); timeEnds[7] = System.currentTimeMillis(); turn++; ruleProcessor.beginTurn(); timeEnds[8] = System.currentTimeMillis(); } finally { playerContainer.getLock().releaseLock(); timeEnds[9] = System.currentTimeMillis(); } try { stats.set("Objects now", world.size()); } catch (ConcurrentModificationException e) { // TODO: size is obviously not threadsafe as it asks the underlying zone.objects for its // sizes, which are not threadsafe. } timeEnds[10] = System.currentTimeMillis(); TransactionPool.get().kickHangingTransactionsOfThisThread(); timeEnds[11] = System.currentTimeMillis(); } } catch (Throwable e) { logger.error("Unhandled exception, server will shut down.", e); } finally { isfinished = true; } }
/** * This method is called when a player is added to the game * * @param object player object * @return true, to continue, false to cause an error * @throws RPObjectInvalidException if the object was invalid */ public boolean onInit(RPObject object) throws RPObjectInvalidException { if (!DebugInterface.get().onInit(object)) { return false; } return ruleProcessor.onInit(object); }
/** * This method decide if an client runs a compatible version of the game * * @param game the game name * @param version the game version as a string * @return true if it is compatible. */ public boolean checkGameVersion(String game, String version) { return ruleProcessor.checkGameVersion(game, version); }