001    package net.minecraft.command;
002    
003    import java.util.ArrayList;
004    import java.util.HashMap;
005    import java.util.HashSet;
006    import java.util.Iterator;
007    import java.util.List;
008    import java.util.Map;
009    import java.util.Set;
010    import java.util.Map.Entry;
011    import net.minecraft.entity.player.EntityPlayerMP;
012    
013    import net.minecraftforge.common.MinecraftForge;
014    import net.minecraftforge.event.CommandEvent;
015    
016    public 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    }