001    package org.bukkit.event.player;
002    
003    import java.util.HashSet;
004    import java.util.Set;
005    
006    import org.apache.commons.lang.Validate;
007    import org.bukkit.entity.Player;
008    import org.bukkit.event.Cancellable;
009    import org.bukkit.event.HandlerList;
010    
011    /**
012     * This event is called whenever a player runs a command (by placing a slash
013     * at the start of their message). It is called early in the command handling
014     * process, and modifications in this event (via {@link #setMessage(String)})
015     * will be shown in the behavior.
016     * <p>
017     * Many plugins will have <b>no use for this event</b>, and you should
018     * attempt to avoid using it if it is not necessary.
019     * <p>
020     * Some examples of valid uses for this event are:
021     * <ul>
022     * <li>Logging executed commands to a separate file
023     * <li>Variable substitution. For example, replacing
024     *     <code>${nearbyPlayer}</code> with the name of the nearest other
025     *     player, or simulating the <code>@a</code> and <code>@p</code>
026     *     decorators used by Command Blocks in plugins that do not handle it.
027     * <li>Conditionally blocking commands belonging to other plugins. For
028     *     example, blocking the use of the <code>/home</code> command in a
029     *     combat arena.
030     * <li>Per-sender command aliases. For example, after a player runs the
031     *     command <code>/calias cr gamemode creative</code>, the next time they
032     *     run <code>/cr</code>, it gets replaced into
033     *     <code>/gamemode creative</code>. (Global command aliases should be
034     *     done by registering the alias.)
035     * </ul>
036     * <p>
037     * Examples of incorrect uses are:
038     * <ul>
039     * <li>Using this event to run command logic
040     * </ul>
041     * <p>
042     * If the event is cancelled, processing of the command will halt.
043     * <p>
044     * The state of whether or not there is a slash (<code>/</code>) at the
045     * beginning of the message should be preserved. If a slash is added or
046     * removed, unexpected behavior may result.
047     */
048    public class PlayerCommandPreprocessEvent extends PlayerEvent implements Cancellable {
049        private static final HandlerList handlers = new HandlerList();
050        private boolean cancel = false;
051        private String message;
052        private String format = "<%1$s> %2$s";
053        private final Set<Player> recipients;
054    
055        public PlayerCommandPreprocessEvent(final Player player, final String message) {
056            super(player);
057            this.recipients = new HashSet<Player>(player.getServer().getOnlinePlayers());
058            this.message = message;
059        }
060    
061        public PlayerCommandPreprocessEvent(final Player player, final String message, final Set<Player> recipients) {
062            super(player);
063            this.recipients = recipients;
064            this.message = message;
065        }
066    
067        public boolean isCancelled() {
068            return cancel;
069        }
070    
071        public void setCancelled(boolean cancel) {
072            this.cancel = cancel;
073        }
074    
075        /**
076         * Gets the command that the player is attempting to send.
077         * <p>
078         * All commands begin with a special character; implementations do not
079         * consider the first character when executing the content.
080         *
081         * @return Message the player is attempting to send
082         */
083        public String getMessage() {
084            return message;
085        }
086    
087        /**
088         * Sets the command that the player will send.
089         * <p>
090         * All commands begin with a special character; implementations do not
091         * consider the first character when executing the content.
092         *
093         * @param command New message that the player will send
094         * @throws IllegalArgumentException if command is null or empty
095         */
096        public void setMessage(String command) throws IllegalArgumentException {
097            Validate.notNull(command, "Command cannot be null");
098            Validate.notEmpty(command, "Command cannot be empty");
099            this.message = command;
100        }
101    
102        /**
103         * Sets the player that this command will be executed as.
104         *
105         * @param player New player which this event will execute as
106         * @throws IllegalArgumentException if the player provided is null
107         */
108        public void setPlayer(final Player player) throws IllegalArgumentException {
109            Validate.notNull(player, "Player cannot be null");
110            this.player = player;
111        }
112    
113        /**
114         * Gets the format to use to display this chat message
115         *
116         * @deprecated This method is provided for backward compatibility with no
117         *     guarantee to the use of the format.
118         * @return String.Format compatible format string
119         */
120        @Deprecated
121        public String getFormat() {
122            return format;
123        }
124    
125        /**
126         * Sets the format to use to display this chat message
127         *
128         * @deprecated This method is provided for backward compatibility with no
129         *     guarantee to the effect of modifying the format.
130         * @param format String.Format compatible format string
131         */
132        @Deprecated
133        public void setFormat(final String format) {
134            // Oh for a better way to do this!
135            try {
136                String.format(format, player, message);
137            } catch (RuntimeException ex) {
138                ex.fillInStackTrace();
139                throw ex;
140            }
141    
142            this.format = format;
143        }
144    
145        /**
146         * Gets a set of recipients that this chat message will be displayed to.
147         * <p>
148         * The set returned is not guaranteed to be mutable and may auto-populate
149         * on access. Any listener accessing the returned set should be aware that
150         * it may reduce performance for a lazy set implementation. Listeners
151         * should be aware that modifying the list may throw {@link
152         * UnsupportedOperationException} if the event caller provides an
153         * unmodifiable set.
154         *
155         * @deprecated This method is provided for backward compatibility with no
156         *     guarantee to the effect of viewing or modifying the set.
157         * @return All Players who will see this chat message
158         */
159        @Deprecated
160        public Set<Player> getRecipients() {
161            return recipients;
162        }
163    
164        @Override
165        public HandlerList getHandlers() {
166            return handlers;
167        }
168    
169        public static HandlerList getHandlerList() {
170            return handlers;
171        }
172    }