package net.sf.arianne.marboard.server.core.engine;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import marauroa.common.crypto.Hash;
import marauroa.common.game.AccountResult;
import marauroa.common.game.CharacterResult;
import marauroa.common.game.RPAction;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPObjectInvalidException;
import marauroa.common.game.RPObjectNotFoundException;
import marauroa.common.game.Result;
import marauroa.server.db.DBTransaction;
import marauroa.server.db.TransactionPool;
import marauroa.server.game.db.AccountDAO;
import marauroa.server.game.db.CharacterDAO;
import marauroa.server.game.db.DAORegister;
import marauroa.server.game.db.DatabaseFactory;
import marauroa.server.game.rp.IRPRuleProcessor;
import marauroa.server.game.rp.RPServerManager;
import marauroa.server.game.rp.RPWorld;
import net.sf.arianne.marboard.server.action.Action;
import net.sf.arianne.marboard.server.action.ActionFactory;
import net.sf.arianne.marboard.server.entity.meta.User;
import org.apache.log4j.Logger;
/**
* handles the "game" rules.
*
* @author hendrik
*/
public class MarboardRuleProcessor implements IRPRuleProcessor {
private static MarboardRuleProcessor instance;
private static final Logger logger = Logger.getLogger(MarboardRuleProcessor.class);
private TransactionPool transactionPool;
private RPWorld world;
private List<RPObject> users;
private ActionFactory actionFactory;
/**
* creates a new MarboardRuleProcessor
*/
private MarboardRuleProcessor() {
new DatabaseFactory().initializeDatabase();
transactionPool = TransactionPool.get();
world = MarboardWorld.get();
users = new LinkedList<RPObject>();
actionFactory = new ActionFactory();
actionFactory.register();
}
/**
* gets the MarboardRuleProcessor (creating it if did not exist before).
*
* @return MarboardRuleProcessor
*/
public static IRPRuleProcessor get() {
if (instance == null) {
instance = new MarboardRuleProcessor();
}
return instance;
}
/**
* ignored
*/
public void beginTurn() {
// empty
}
/**
* checks the game name and version of the client. We currently accept everything.
*
* @param game name of game-client
* @param version version of client
*/
public boolean checkGameVersion(String game, String version) {
return true;
}
/**
* Create an account for a player.
*/
public AccountResult createAccount(String username, String password, String email) {
// check a minimum length for username and password.
if ((username.length() < 4) || (password.length() < 4)) {
return new AccountResult(Result.FAILED_STRING_SIZE, username);
}
DBTransaction transaction = transactionPool.beginWork();
try {
if (DAORegister.get().get(AccountDAO.class).hasPlayer(transaction, username)) {
logger.warn("Account already exist: " + username);
transactionPool.commit(transaction);
return new AccountResult(Result.FAILED_PLAYER_EXISTS, username);
}
DAORegister.get().get(AccountDAO.class).addPlayer(transaction, username, Hash.hash(password), email);
transactionPool.commit(transaction);
return new AccountResult(Result.OK_CREATED, username);
} catch (SQLException e) {
transactionPool.rollback(transaction);
return new AccountResult(Result.FAILED_EXCEPTION, username);
}
}
/**
* Create a character for a player
*/
public CharacterResult createCharacter(String username, String character, RPObject template) {
DBTransaction transaction = transactionPool.beginWork();
try {
RPObject user = new RPObject(template);
user.setRPClass("user");
user.put("name", character);
if (DAORegister.get().get(CharacterDAO.class).hasCharacter(transaction, username, character)) {
logger.warn("Character already exist: " + character);
return new CharacterResult(Result.FAILED_PLAYER_EXISTS, character, user);
}
DAORegister.get().get(CharacterDAO.class).addCharacter(transaction, username, character, user);
transactionPool.commit(transaction);
return new CharacterResult(Result.OK_CREATED, character, user);
} catch (Exception e) {
transactionPool.rollback(transaction);
return new CharacterResult(Result.FAILED_EXCEPTION, character, template);
}
}
/**
* ignored
*/
public void endTurn() {
// empty
}
/**
* executes an action requested by the client
*
* @param caster the user performing this action
* @param action the action to be performed provided by marauroa
*/
public void execute(RPObject caster, RPAction action) {
Action actionHandler = actionFactory.create(action.get("type"));
actionHandler.onAction((User) caster, action);
}
/**
* This method is called *before* adding an action by RPScheduler so you can
* choose not to allow the action to be added by returning false
*
* @param object
* the object that casted the action
* @param action
* the action that is going to be added.
* @param actionList
* the actions that this player already owns.
* @return always true
*/
public boolean onActionAdd(RPObject object, RPAction action, List<RPAction> actionList) {
return true;
}
/**
* removes a client from the world.
*
* @param object object representing the user
*/
public boolean onExit(RPObject object) throws RPObjectNotFoundException {
world.remove(object.getID());
users.remove(object);
return true;
}
/**
* adds a user to the world.
*
* @param object object representing the user
*/
public boolean onInit(RPObject object) throws RPObjectInvalidException {
object.put("zoneid", "initial_zone");
users.add(object);
world.add(object);
return true;
}
/**
* times out a user.
*
* @param object object representing the user
*/
public void onTimeout(RPObject object) throws RPObjectNotFoundException {
logger.warn("Client " + object.get("name") + " timeout");
onExit(object);
}
/**
* ignored
*
* @param rpman RPServerManager
*/
public void setContext(RPServerManager rpman) {
// empty
}
}