CommandParser.java
package com.jadventure.game.prompts;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.TreeMap;
import com.jadventure.game.DeathException;
import com.jadventure.game.QueueProvider;
import com.jadventure.game.entities.Player;
/**
* CommandParser parses the game commands
*
* It parses all the commands automatically.
* To add a new command, you just need to make addition in the CommandCollection.
*/
public class CommandParser {
Player player;
private TreeMap<String, Method> commandMap;
public CommandParser(Player player){
this.player = player;
commandMap = new TreeMap<String, Method>();
initCommandMap();
}
// adds the command to the commandMap
private void initCommandMap() {
Method[] methods = CommandCollection.class.getMethods();
for(Method method: methods){
if (!method.isAnnotationPresent(Command.class)) {
continue;
}
Command annotation = method.getAnnotation(Command.class);
this.commandMap.put(annotation.command(), method);
for(String alias : annotation.aliases().split(",")){
if (alias.length() == 0) {
break;
}
this.commandMap.put(alias, method);
}
}
}
public boolean parse(Player player, String userCommand) throws DeathException {
CommandCollection com = CommandCollection.getInstance();
com.initPlayer(player);
if (userCommand.equals("exit")) {
return false;
}
String command = removeNaturalText(userCommand);
// descendingKeySet otherwise startsWith will return correspond to longer command
// e.g. 'de' will match startWith('d')
for (String key : commandMap.descendingKeySet()) {
if (command.startsWith(key)) {
Method method = commandMap.get(key);
if (method.getParameterTypes().length == 0){
if (command.equals(key)) {
try {
if (method.getAnnotation(Command.class).debug()) {
if ("test".equals(player.getName())) {
method.invoke(com);
} else {
QueueProvider.offer("Must be using test profile to debug");
}
} else {
method.invoke(com);
}
} catch (IllegalAccessException | InvocationTargetException e) {
if (e.getCause() instanceof DeathException) {
throw (DeathException) e.getCause();
} else {
e.getCause().printStackTrace();
}
}
} else {
QueueProvider.offer("I don't know what'" + userCommand + "' means.");
return true;
}
} else if (method.getParameterTypes()[0] == String.class) {
String arg = command.substring(key.length()).trim();
try {
if (method.getAnnotation(Command.class).debug()) {
if ("test".equals(player.getName())) {
method.invoke(com, arg);
} else {
QueueProvider.offer("Must be using test profile to debug");
}
} else {
method.invoke(com, arg);
}
} catch (IllegalAccessException | InvocationTargetException e) {
if (e.getCause() instanceof DeathException) {
throw (DeathException) e.getCause();
} else {
e.getCause().printStackTrace();
}
}
}
return true;
}
}
QueueProvider.offer("I don't know what'" + userCommand + "' means.");
return true;
}
private String removeNaturalText(String command) {
command = command.replaceAll(" to ", " ");
command = command.replaceAll(" a ", " ");
return command;
}
}