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}