    001package net.minecraft.command;
    002
    003import java.util.ArrayList;
    004import java.util.HashMap;
    005import java.util.HashSet;
    006import java.util.Iterator;
    007import java.util.List;
    008import java.util.Map;
    009import java.util.Set;
    010import java.util.Map.Entry;
    011import net.minecraft.entity.player.EntityPlayerMP;
    012import net.minecraft.util.EnumChatFormatting;
    013
    014import net.minecraftforge.common.MinecraftForge;
    015import net.minecraftforge.event.CommandEvent;
    016
    017public class CommandHandler implements ICommandManager
    018{
    019    /** Map of Strings to the ICommand objects they represent */
    020    private final Map commandMap = new HashMap();
    021
    022    /** The set of ICommand objects currently loaded. */
    023    private final Set commandSet = new HashSet();
    024
    025    public int executeCommand(ICommandSender par1ICommandSender, String par2Str)
    026    {
    027        par2Str = par2Str.trim();
    028
    029        if (par2Str.startsWith("/"))
    030        {
    031            par2Str = par2Str.substring(1);
    032        }
    033
    034        String[] astring = par2Str.split(" ");
    035        String s1 = astring[0];
    036        astring = dropFirstString(astring);
    037        ICommand icommand = (ICommand)this.commandMap.get(s1);
    038        int i = this.getUsernameIndex(icommand, astring);
    039        int j = 0;
    040
    041        try
    042        {
    043            if (icommand == null)
    044            {
    045                throw new CommandNotFoundException();
    046            }
    047
    048            if (icommand.canCommandSenderUseCommand(par1ICommandSender))
    049            {
    050                CommandEvent event = new CommandEvent(icommand, par1ICommandSender, astring);
    051                if (MinecraftForge.EVENT_BUS.post(event))
    052                {
    053                    if (event.exception != null)
    054                    {
    055                        throw event.exception;
    056                    }
    057                    return 1;
    058                }
    059
    060                if (i > -1)
    061                {
    062                    EntityPlayerMP[] aentityplayermp = PlayerSelector.matchPlayers(par1ICommandSender, astring[i]);
    063                    String s2 = astring[i];
    064                    EntityPlayerMP[] aentityplayermp1 = aentityplayermp;
    065                    int k = aentityplayermp.length;
    066
    067                    for (int l = 0; l < k; ++l)
    068                    {
    069                        EntityPlayerMP entityplayermp = aentityplayermp1[l];
    070                        astring[i] = entityplayermp.getEntityName();
    071
    072                        try
    073                        {
    074                            icommand.processCommand(par1ICommandSender, astring);
    075                            ++j;
    076                        }
    077                        catch (CommandException commandexception)
    078                        {
    079                            par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + par1ICommandSender.translateString(commandexception.getMessage(), commandexception.getErrorOjbects()));
    080                        }
    081                    }
    082
    083                    astring[i] = s2;
    084                }
    085                else
    086                {
    087                    icommand.processCommand(par1ICommandSender, astring);
    088                    ++j;
    089                }
    090            }
    091            else
    092            {
    093                par1ICommandSender.sendChatToPlayer("" + EnumChatFormatting.RED + "You do not have permission to use this command.");
    094            }
    095        }
    096        catch (WrongUsageException wrongusageexception)
    097        {
    098            par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + par1ICommandSender.translateString("commands.generic.usage", new Object[] {par1ICommandSender.translateString(wrongusageexception.getMessage(), wrongusageexception.getErrorOjbects())}));
    099        }
    100        catch (CommandException commandexception1)
    101        {
    102            par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + par1ICommandSender.translateString(commandexception1.getMessage(), commandexception1.getErrorOjbects()));
    103        }
    104        catch (Throwable throwable)
    105        {
    106            par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + par1ICommandSender.translateString("commands.generic.exception", new Object[0]));
    107            throwable.printStackTrace();
    108        }
    109
    110        return j;
    111    }
    112
    113    /**
    114     * adds the command and any aliases it has to the internal map of available commands
    115     */
    116    public ICommand registerCommand(ICommand par1ICommand)
    117    {
    118        List list = par1ICommand.getCommandAliases();
    119        this.commandMap.put(par1ICommand.getCommandName(), par1ICommand);
    120        this.commandSet.add(par1ICommand);
    121
    122        if (list != null)
    123        {
    124            Iterator iterator = list.iterator();
    125
    126            while (iterator.hasNext())
    127            {
    128                String s = (String)iterator.next();
    129                ICommand icommand1 = (ICommand)this.commandMap.get(s);
    130
    131                if (icommand1 == null || !icommand1.getCommandName().equals(s))
    132                {
    133                    this.commandMap.put(s, par1ICommand);
    134                }
    135            }
    136        }
    137
    138        return par1ICommand;
    139    }
    140
    141    /**
    142     * creates a new array and sets elements 0..n-2 to be 0..n-1 of the input (n elements)
    143     */
    144    private static String[] dropFirstString(String[] par0ArrayOfStr)
    145    {
    146        String[] astring1 = new String[par0ArrayOfStr.length - 1];
    147
    148        for (int i = 1; i < par0ArrayOfStr.length; ++i)
    149        {
    150            astring1[i - 1] = par0ArrayOfStr[i];
    151        }
    152
    153        return astring1;
    154    }
    155
    156    /**
    157     * Performs a "begins with" string match on each token in par2. Only returns commands that par1 can use.
    158     */
    159    public List getPossibleCommands(ICommandSender par1ICommandSender, String par2Str)
    160    {
    161        String[] astring = par2Str.split(" ", -1);
    162        String s1 = astring[0];
    163
    164        if (astring.length == 1)
    165        {
    166            ArrayList arraylist = new ArrayList();
    167            Iterator iterator = this.commandMap.entrySet().iterator();
    168
    169            while (iterator.hasNext())
    170            {
    171                Entry entry = (Entry)iterator.next();
    172
    173                if (CommandBase.doesStringStartWith(s1, (String)entry.getKey()) && ((ICommand)entry.getValue()).canCommandSenderUseCommand(par1ICommandSender))
    174                {
    175                    arraylist.add(entry.getKey());
    176                }
    177            }
    178
    179            return arraylist;
    180        }
    181        else
    182        {
    183            if (astring.length > 1)
    184            {
    185                ICommand icommand = (ICommand)this.commandMap.get(s1);
    186
    187                if (icommand != null)
    188                {
    189                    return icommand.addTabCompletionOptions(par1ICommandSender, dropFirstString(astring));
    190                }
    191            }
    192
    193            return null;
    194        }
    195    }
    196
    197    /**
    198     * returns all commands that the commandSender can use
    199     */
    200    public List getPossibleCommands(ICommandSender par1ICommandSender)
    201    {
    202        ArrayList arraylist = new ArrayList();
    203        Iterator iterator = this.commandSet.iterator();
    204
    205        while (iterator.hasNext())
    206        {
    207            ICommand icommand = (ICommand)iterator.next();
    208
    209            if (icommand.canCommandSenderUseCommand(par1ICommandSender))
    210            {
    211                arraylist.add(icommand);
    212            }
    213        }
    214
    215        return arraylist;
    216    }
    217
    218    /**
    219     * returns a map of string to commads. All commands are returned, not just ones which someone has permission to use.
    220     */
    221    public Map getCommands()
    222    {
    223        return this.commandMap;
    224    }
    225
    226    /**
    227     * Return a command's first parameter index containing a valid username.
    228     */
    229    private int getUsernameIndex(ICommand par1ICommand, String[] par2ArrayOfStr)
    230    {
    231        if (par1ICommand == null)
    232        {
    233            return -1;
    234        }
    235        else
    236        {
    237            for (int i = 0; i < par2ArrayOfStr.length; ++i)
    238            {
    239                if (par1ICommand.isUsernameIndex(par2ArrayOfStr, i) && PlayerSelector.matchesMultiplePlayers(par2ArrayOfStr[i]))
    240                {
    241                    return i;
    242                }
    243            }
    244
    245            return -1;
    246        }
    247    }
    248}