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