package server.command;
import java.util.HashSet;
import java.util.Set;
import server.Emote;
import server.FatalError;
import server.Player;
import server.RoomEntity;
import server.SyntaxException;
public class CommandProcessor {
private static int idx;
private static String cmd;
private static final Set<String> prepositions = new HashSet<String>();
static {
prepositions.add("to");
prepositions.add("at");
prepositions.add("with");
}
public static void process(Player player, Command command, String args) {
idx = 0;
CommandProcessor.cmd = args;
try {
command.run(player);
} catch (SyntaxException e) {
throw new FatalError("Invalid Syntax.", e);
}
}
public static void process(Player player, String newCommand) {
idx = 0;
CommandProcessor.cmd = newCommand;
String token = nextToken();
if (token != null) {
token = token.toLowerCase();
try {
Command command = player.parseCommand(token);
if (command == null) {
Emote spec;
if (player.canEmote() && (spec = Emote.get(token)) != null) {
doEmote(player, token, spec);
}
else if (player.isDead()) {
player.sendText(true, "You seem to be dead. You can use the @10FLIFE@ZZZ command to return to life.");
}
else if (player.isUnconscious()) {
player.sendText(true, "You're unconscious, but should regain consciousness soon.");
}
else {
player.sendText(true, "What?");
}
}
else {
command.run(player);
}
}
catch (SyntaxException ex) {
player.sendText(true, "Invalid syntax. Type @10FHELP " + token.toUpperCase() + "@ZZZ for input patterns.");
}
}
}
private static void doEmote(Player player, String name, Emote spec) throws SyntaxException {
String modifier = null;
String target = null;
while (true) {
String token = nextToken();
if (token == null) {
break;
}
if (spec.getTargetType() != Emote.TargetType.DISALLOWED) {
if (prepositions.contains(token)) {
continue; }
}
String tmp = spec.getModifier(token);
if (tmp != null) {
if (modifier != null) {
throw new SyntaxException();
}
modifier = tmp;
continue;
}
if (spec.getTargetType() != Emote.TargetType.DISALLOWED) {
if (target != null) {
throw new SyntaxException();
}
target = token;
}
else {
throw new SyntaxException();
}
}
if (modifier == null) {
modifier = "";
}
else {
modifier = " " + modifier;
}
if (target != null) {
RoomEntity entity = player.matchLocalRoomEntity(target);
if (entity == null) {
player.sendText(true, "There's noone here by that name.");
}
else {
player.getRoom().sendText(null, spec.getAudioTS(), spec.getVisualTS(), spec.getBothTS(), null, new String[] { modifier }, player, entity);
}
}
else {
if (spec.getTargetType() == Emote.TargetType.REQUIRED) {
player.sendText(true, "A target is required for this emote.");
}
else {
player.getRoom().sendText(null, spec.getAudioTS(), spec.getVisualTS(), spec.getBothTS(), null, new String[] { modifier }, player);
}
}
}
public static void help(Player player, String token) {
token = token.toLowerCase();
Command command = player.parseCommand(token);
if (command == null) {
Emote spec;
if (!player.canEmote() || (spec = Emote.get(token)) == null) {
player.sendText(true, "Unknown help topic: " + token);
return;
}
token = token.toUpperCase();
StringBuffer syntax = new StringBuffer();
syntax.append("@10F@507Syntax@107:@ZZZ ");
syntax.append(token);
Set<String> modifiers = spec.getModifiers();
if (!modifiers.isEmpty()) {
syntax.append(" [modifier]");
}
switch (spec.getTargetType()) {
case REQUIRED: syntax.append(" <target>"); break;
case ALLOWED: syntax.append(" [target]"); break;
case DISALLOWED: break;
}
player.sendText(true, syntax.toString());
if (!modifiers.isEmpty()) {
syntax = new StringBuffer();
for (String modifier : modifiers) {
if (syntax.length() > 0) {
syntax.append(", ");
}
syntax.append(modifier);
}
player.sendText(true, "@10F@207Valid modifiers:@ZZZ " + syntax.toString());
}
return;
}
token = token.toUpperCase();
String[] helpText = command.getHelpText();
if (helpText != null && helpText.length > 0) {
player.sendText(false, "");
for (int i = 0; i < helpText.length; i++) {
player.sendText(false, helpText[i]);
}
}
String[] syntax = command.getSyntax(player);
player.sendText(true, "@10F@507Syntax@107:@ZZZ " + token + " " + syntax[0]);
for (int i = 1; i < syntax.length; i++) {
player.sendText(false, "@10F " + token + " " + syntax[i]);
}
}
static String nextToken() {
String token = nextTokenPreserveCase();
return token == null ? null : token.toLowerCase();
}
static String nextTokenPreserveCase() {
while (true) {
if (idx >= cmd.length()) {
return null; }
int end = cmd.indexOf(' ', idx);
if (end < 0) {
end = cmd.length();
}
if (end > idx) {
String token = cmd.substring(idx, end);
idx = end + 1; return token.trim();
}
idx++;
}
}
static String nextTokenAllowQuotes() {
return nextTokenAllowQuotes(false);
}
static String getRemainingAllowQuotes() {
return nextTokenAllowQuotes(true);
}
private static String nextTokenAllowQuotes(boolean restOfLine) {
char[] c = cmd.toCharArray();
while (true) {
if (idx >= c.length) {
return null; }
if (c[idx] != ' ') {
break;
}
idx++;
}
StringBuffer sb = new StringBuffer();
while (true) {
if (idx >= c.length) {
return sb.toString();
}
switch (c[idx]) {
case '"': {
int end = cmd.indexOf('"', idx + 1);
if (end < 0) {
end = cmd.length();
}
sb.append(c, idx + 1, end - idx - 1);
idx = end;
break;
}
case ' ': {
if (!restOfLine) {
idx++; return sb.toString();
}
}
default: sb.append(c[idx]);
}
idx++;
}
}
static String getRemaining() {
String s = "";
if (idx < cmd.length()) {
s = cmd.substring(idx);
}
idx = cmd.length();
return s.trim();
}
}