001    package org.bukkit.command.defaults;
002    
003    import java.util.ArrayList;
004    import java.util.Arrays;
005    import java.util.List;
006    
007    import org.apache.commons.lang.Validate;
008    import org.bukkit.Achievement;
009    import org.bukkit.Bukkit;
010    import org.bukkit.ChatColor;
011    import org.bukkit.Statistic;
012    import org.bukkit.Material;
013    import org.bukkit.Statistic.Type;
014    import org.bukkit.command.Command;
015    import org.bukkit.command.CommandSender;
016    import org.bukkit.entity.EntityType;
017    import org.bukkit.entity.Player;
018    import org.bukkit.event.player.PlayerAchievementAwardedEvent;
019    import org.bukkit.event.player.PlayerStatisticIncrementEvent;
020    
021    import com.google.common.collect.ImmutableList;
022    
023    public class AchievementCommand extends VanillaCommand {
024        public AchievementCommand() {
025            super("achievement");
026            this.description = "Gives the specified player an achievement or changes a statistic value. Use '*' to give all achievements.";
027            this.usageMessage = "/achievement give <stat_name> [player]";
028            this.setPermission("bukkit.command.achievement");
029        }
030    
031        @Override
032        public boolean execute(CommandSender sender, String currentAlias, String[] args) {
033            if (!testPermission(sender)) return true;
034    
035            if (args.length < 2) {
036                sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
037                return false;
038            }
039    
040            if (!args[0].equalsIgnoreCase("give")) {
041                sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
042                return false;
043            }
044    
045            String statisticString = args[1];
046            Player player = null;
047    
048            if (args.length > 2) {
049                player = Bukkit.getPlayer(args[1]);
050            } else if (sender instanceof Player) {
051                player = (Player) sender;
052            }
053    
054            if (player == null) {
055                sender.sendMessage("You must specify which player you wish to perform this action on.");
056                return true;
057            }
058    
059            if (statisticString.equals("*")) {
060                for (Achievement achievement : Achievement.values()) {
061                    if (player.hasAchievement(achievement)) {
062                        continue;
063                    }
064                    PlayerAchievementAwardedEvent event = new PlayerAchievementAwardedEvent(player, achievement);
065                    Bukkit.getServer().getPluginManager().callEvent(event);
066                    if (!event.isCancelled()) {
067                        player.awardAchievement(achievement);
068                    }
069                }
070                Command.broadcastCommandMessage(sender, String.format("Successfully given all achievements to %s", player.getName()));
071                return true;
072            }
073    
074            Achievement achievement = Bukkit.getUnsafe().getAchievementFromInternalName(statisticString);
075            Statistic statistic = Bukkit.getUnsafe().getStatisticFromInternalName(statisticString);
076    
077            if (achievement != null) {
078                if (player.hasAchievement(achievement)) {
079                    sender.sendMessage(String.format("%s already has achievement %s", player.getName(), statisticString));
080                    return true;
081                }
082    
083                PlayerAchievementAwardedEvent event = new PlayerAchievementAwardedEvent(player, achievement);
084                Bukkit.getServer().getPluginManager().callEvent(event);
085                if (event.isCancelled()) {
086                    sender.sendMessage(String.format("Unable to award %s the achievement %s", player.getName(), statisticString));
087                    return true;
088                }
089                player.awardAchievement(achievement);
090                    
091                Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString));
092                return true;
093            }
094    
095            if (statistic == null) {
096                sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
097                return true;
098            }
099    
100            if (statistic.getType() == Type.UNTYPED) {
101                PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1);
102                Bukkit.getServer().getPluginManager().callEvent(event);
103                if (event.isCancelled()) {
104                    sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName()));
105                    return true;
106                }
107                player.incrementStatistic(statistic);
108                Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString));
109                return true;
110            }
111    
112            if (statistic.getType() == Type.ENTITY) {
113                EntityType entityType = EntityType.fromName(statisticString.substring(statisticString.lastIndexOf(".") + 1));
114    
115                if (entityType == null) {
116                    sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
117                    return true;
118                }
119    
120                PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1, entityType);
121                Bukkit.getServer().getPluginManager().callEvent(event);
122                if (event.isCancelled()) {
123                    sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName()));
124                    return true;
125                }
126    
127                try {
128                    player.incrementStatistic(statistic, entityType);
129                } catch (IllegalArgumentException e) {
130                    sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
131                    return true;
132                }
133            } else {
134                int id;
135                try {
136                    id = getInteger(sender, statisticString.substring(statisticString.lastIndexOf(".") + 1), 0, Integer.MAX_VALUE, true);
137                } catch (NumberFormatException e) {
138                    sender.sendMessage(e.getMessage());
139                    return true;
140                }
141    
142                Material material = Material.getMaterial(id);
143    
144                if (material == null) {
145                    sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
146                    return true;
147                }
148    
149                PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1, material);
150                Bukkit.getServer().getPluginManager().callEvent(event);
151                if (event.isCancelled()) {
152                    sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName()));
153                    return true;
154                }
155    
156                try {
157                    player.incrementStatistic(statistic, material);
158                } catch (IllegalArgumentException e) {
159                    sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
160                    return true;
161                }
162            }
163    
164            Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString));
165            return true;
166        }
167    
168        @Override
169        public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
170            Validate.notNull(sender, "Sender cannot be null");
171            Validate.notNull(args, "Arguments cannot be null");
172            Validate.notNull(alias, "Alias cannot be null");
173    
174            if (args.length == 1) {
175                return Arrays.asList("give");
176            }
177    
178            if (args.length == 2) {
179                return Bukkit.getUnsafe().tabCompleteInternalStatisticOrAchievementName(args[1], new ArrayList<String>());
180            }
181    
182            if (args.length == 3) {
183                return super.tabComplete(sender, alias, args);
184            }
185            return ImmutableList.of();
186        }
187    }