001    package org.bukkit.command.defaults;
002    
003    import java.util.ArrayList;
004    import java.util.Arrays;
005    import java.util.Collections;
006    import java.util.List;
007    
008    import org.apache.commons.lang.Validate;
009    import org.bukkit.Bukkit;
010    import org.bukkit.ChatColor;
011    import org.bukkit.Material;
012    import org.bukkit.command.Command;
013    import org.bukkit.command.CommandSender;
014    import org.bukkit.entity.Player;
015    import org.bukkit.inventory.ItemStack;
016    import org.bukkit.util.StringUtil;
017    
018    import com.google.common.base.Joiner;
019    import com.google.common.collect.ImmutableList;
020    
021    public class GiveCommand extends VanillaCommand {
022        private static List<String> materials;
023        static {
024            ArrayList<String> materialList = new ArrayList<String>();
025            for (Material material : Material.values()) {
026                materialList.add(material.name());
027            }
028            Collections.sort(materialList);
029            materials = ImmutableList.copyOf(materialList);
030        }
031    
032        public GiveCommand() {
033            super("give");
034            this.description = "Gives the specified player a certain amount of items";
035            this.usageMessage = "/give <player> <item> [amount [data]]";
036            this.setPermission("bukkit.command.give");
037        }
038    
039        @Override
040        public boolean execute(CommandSender sender, String currentAlias, String[] args) {
041            if (!testPermission(sender)) return true;
042            if ((args.length < 2)) {
043                sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
044                return false;
045            }
046    
047            Player player = Bukkit.getPlayerExact(args[0]);
048    
049            if (player != null) {
050                Material material = Material.matchMaterial(args[1]);
051    
052                if (material == null) {
053                    material = Bukkit.getUnsafe().getMaterialFromInternalName(args[1]);
054                }
055    
056                if (material != null) {
057                    int amount = 1;
058                    short data = 0;
059    
060                    if (args.length >= 3) {
061                        amount = this.getInteger(sender, args[2], 1, 64);
062    
063                        if (args.length >= 4) {
064                            try {
065                                data = Short.parseShort(args[3]);
066                            } catch (NumberFormatException ex) {}
067                        }
068                    }
069    
070                    ItemStack stack = new ItemStack(material, amount, data);
071    
072                    if (args.length >= 5) {
073                        try {
074                            stack = Bukkit.getUnsafe().modifyItemStack(stack, Joiner.on(' ').join(Arrays.asList(args).subList(4, args.length)));
075                        } catch (Throwable t) {
076                            player.sendMessage("Not a valid tag");
077                            return true;
078                        }
079                    }
080    
081                    player.getInventory().addItem(stack);
082    
083                    Command.broadcastCommandMessage(sender, "Gave " + player.getName() + " some " + material.getId() + " (" + material + ")");
084                } else {
085                    sender.sendMessage("There's no item called " + args[1]);
086                }
087            } else {
088                sender.sendMessage("Can't find player " + args[0]);
089            }
090    
091            return true;
092        }
093    
094        @Override
095        public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
096            Validate.notNull(sender, "Sender cannot be null");
097            Validate.notNull(args, "Arguments cannot be null");
098            Validate.notNull(alias, "Alias cannot be null");
099    
100            if (args.length == 1) {
101                return super.tabComplete(sender, alias, args);
102            }
103            if (args.length == 2) {
104                final String arg = args[1];
105                final List<String> materials = GiveCommand.materials;
106                List<String> completion = new ArrayList<String>();
107    
108                final int size = materials.size();
109                int i = Collections.binarySearch(materials, arg, String.CASE_INSENSITIVE_ORDER);
110    
111                if (i < 0) {
112                    // Insertion (start) index
113                    i = -1 - i;
114                }
115    
116                for ( ; i < size; i++) {
117                    String material = materials.get(i);
118                    if (StringUtil.startsWithIgnoreCase(material, arg)) {
119                        completion.add(material);
120                    } else {
121                        break;
122                    }
123                }
124    
125                return Bukkit.getUnsafe().tabCompleteInternalMaterialName(arg, completion);
126            }
127            return ImmutableList.of();
128        }
129    }