package com.forgeessentials.scripting;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import org.apache.commons.lang3.StringUtils;
import com.forgeessentials.util.output.LoggingHandler;
public class ScriptParser
{
public static interface ScriptMethod
{
public boolean process(ICommandSender sender, String[] args);
public String getHelp();
}
public static interface ScriptArgument
{
public String process(ICommandSender sender) throws ScriptException;
public String getHelp();
}
private static final Pattern ARGUMENT_PATTERN = Pattern.compile("@(\\w+)(.*)");
public static String[] processArguments(ICommandSender sender, String[] actionArgs, List<String> args)
{
for (int i = 0; i < actionArgs.length; i++)
{
Matcher matcher = ARGUMENT_PATTERN.matcher(actionArgs[i]);
if (!matcher.matches())
continue;
String modifier = matcher.group(1).toLowerCase();
String rest = matcher.group(2);
ScriptArgument argument = ScriptArguments.get(modifier);
if (argument != null)
{
actionArgs[i] = argument.process(sender) + rest;
}
else
{
try
{
int idx = Integer.parseInt(modifier);
if (args == null || idx >= args.size())
throw new SyntaxException("Missing argument @%d", idx);
actionArgs[i] = args.get(idx) + rest;
}
catch (NumberFormatException e)
{
throw new SyntaxException("Unknown argument modifier \"%s\"", modifier);
}
}
}
return actionArgs;
}
public static void run(List<String> script)
{
run(script, null);
}
public static void run(List<String> script, ICommandSender sender)
{
run(script, sender, null);
}
public static boolean run(List<String> script, ICommandSender sender, List<String> args)
{
for (String action : script)
if (!run(action, sender, args))
return false;
return true;
}
public static boolean run(String action, ICommandSender sender, List<String> argumentValues)
{
String[] args = action.split(" ", 2);
String cmd = args[0].toLowerCase();
args = args.length > 1 ? args[1].split(" ") : new String[0];
args = processArguments(sender, args, argumentValues);
if (cmd.length() > 1 && cmd.charAt(0) == '/')
{
// Run command
cmd = cmd.substring(1);
boolean ignorePermissions = cmd.equals("p") || cmd.equals("feperm");
ICommand mcCommand = (ICommand) MinecraftServer.getServer().getCommandManager().getCommands().get(cmd);
mcCommand.processCommand(ignorePermissions ? MinecraftServer.getServer() : sender, args);
}
else if (cmd.length() > 2 && cmd.charAt(0) == '?' && cmd.charAt(1) == '/')
{
// Run command silently (execution won't fail if command fails)
cmd = cmd.substring(2);
boolean ignorePermissions = cmd.equals("p") || cmd.equals("feperm");
ICommand mcCommand = (ICommand) MinecraftServer.getServer().getCommandManager().getCommands().get(cmd);
try
{
mcCommand.processCommand(ignorePermissions ? MinecraftServer.getServer() : sender, args);
}
catch (CommandException e)
{
LoggingHandler.felog.info(String.format("Silent script command /%s %s failed: %s", cmd, StringUtils.join(args, " "), e.getMessage()));
}
}
else if (cmd.length() > 2 && cmd.charAt(0) == '$' && cmd.charAt(1) == '/')
{
// Run command as server
cmd = cmd.substring(2);
ICommand mcCommand = (ICommand) MinecraftServer.getServer().getCommandManager().getCommands().get(cmd);
try
{
mcCommand.processCommand(MinecraftServer.getServer(), args);
}
catch (CommandException e)
{
LoggingHandler.felog.info(String.format("Silent script command /%s %s failed: %s", cmd, StringUtils.join(args, " "), e.getMessage()));
}
}
else
{
boolean canFail = false;
if (cmd.length() > 1 && cmd.charAt(0) == '?')
{
canFail = true;
cmd = cmd.substring(1);
}
ScriptMethod method = ScriptMethods.get(cmd);
if (method == null)
throw new SyntaxException("Unknown script method \"%s\"", cmd);
return method.process(sender, args) | canFail;
}
return true;
}
public static class ScriptException extends RuntimeException
{
public ScriptException()
{
super();
}
public ScriptException(String message)
{
super(message);
}
public ScriptException(String message, Object... args)
{
super(String.format(message, args));
}
}
public static class SyntaxException extends ScriptException
{
public SyntaxException(String message, Object... args)
{
super(message, args);
}
}
public static class MissingPlayerException extends ScriptException
{
public MissingPlayerException()
{
super("Missing player for @player argument");
}
}
public static class MissingPermissionException extends ScriptException
{
public final String permission;
public MissingPermissionException(String permission, String message)
{
super(message);
this.permission = permission;
}
public MissingPermissionException(String permission, String message, Object... args)
{
super(message, args);
this.permission = permission;
}
}
}