001    package org.bukkit.event.player;
002    
003    import java.util.IllegalFormatException;
004    import java.util.Set;
005    
006    import org.bukkit.entity.Player;
007    import org.bukkit.event.Cancellable;
008    import org.bukkit.event.HandlerList;
009    
010    /**
011     * This event will sometimes fire synchronously, depending on how it was
012     * triggered.
013     * <p>
014     * The constructor provides a boolean to indicate if the event was fired
015     * synchronously or asynchronously. When asynchronous, this event can be
016     * called from any thread, sans the main thread, and has limited access to the
017     * API.
018     * <p>
019     * If a player is the direct cause of this event by an incoming packet, this
020     * event will be asynchronous. If a plugin triggers this event by compelling a
021     * player to chat, this event will be synchronous.
022     * <p>
023     * Care should be taken to check {@link #isAsynchronous()} and treat the event
024     * appropriately.
025     */
026    public class AsyncPlayerChatEvent extends PlayerEvent implements Cancellable {
027        private static final HandlerList handlers = new HandlerList();
028        private boolean cancel = false;
029        private String message;
030        private String format = "<%1$s> %2$s";
031        private final Set<Player> recipients;
032    
033        /**
034         *
035         * @param async This changes the event to a synchronous state.
036         * @param who the chat sender
037         * @param message the message sent
038         * @param players the players to receive the message. This may be a lazy
039         *     or unmodifiable collection.
040         */
041        public AsyncPlayerChatEvent(final boolean async, final Player who, final String message, final Set<Player> players) {
042            super(who, async);
043            this.message = message;
044            recipients = players;
045        }
046    
047        /**
048         * Gets the message that the player is attempting to send. This message
049         * will be used with {@link #getFormat()}.
050         *
051         * @return Message the player is attempting to send
052         */
053        public String getMessage() {
054            return message;
055        }
056    
057        /**
058         * Sets the message that the player will send. This message will be used
059         * with {@link #getFormat()}.
060         *
061         * @param message New message that the player will send
062         */
063        public void setMessage(String message) {
064            this.message = message;
065        }
066    
067        /**
068         * Gets the format to use to display this chat message.
069         * <p>
070         * When this event finishes execution, the first format parameter is the
071         * {@link Player#getDisplayName()} and the second parameter is {@link
072         * #getMessage()}
073         *
074         * @return {@link String#format(String, Object...)} compatible format
075         *     string
076         */
077        public String getFormat() {
078            return format;
079        }
080    
081        /**
082         * Sets the format to use to display this chat message.
083         * <p>
084         * When this event finishes execution, the first format parameter is the
085         * {@link Player#getDisplayName()} and the second parameter is {@link
086         * #getMessage()}
087         *
088         * @param format {@link String#format(String, Object...)} compatible
089         *     format string
090         * @throws IllegalFormatException if the underlying API throws the
091         *     exception
092         * @throws NullPointerException if format is null
093         * @see String#format(String, Object...)
094         */
095        public void setFormat(final String format) throws IllegalFormatException, NullPointerException {
096            // Oh for a better way to do this!
097            try {
098                String.format(format, player, message);
099            } catch (RuntimeException ex) {
100                ex.fillInStackTrace();
101                throw ex;
102            }
103    
104            this.format = format;
105        }
106    
107        /**
108         * Gets a set of recipients that this chat message will be displayed to.
109         * <p>
110         * The set returned is not guaranteed to be mutable and may auto-populate
111         * on access. Any listener accessing the returned set should be aware that
112         * it may reduce performance for a lazy set implementation.
113         * <p>
114         * Listeners should be aware that modifying the list may throw {@link
115         * UnsupportedOperationException} if the event caller provides an
116         * unmodifiable set.
117         *
118         * @return All Players who will see this chat message
119         */
120        public Set<Player> getRecipients() {
121            return recipients;
122        }
123    
124        public boolean isCancelled() {
125            return cancel ;
126        }
127    
128        public void setCancelled(boolean cancel) {
129            this.cancel = cancel;
130        }
131    
132        @Override
133        public HandlerList getHandlers() {
134            return handlers;
135        }
136    
137        public static HandlerList getHandlerList() {
138            return handlers;
139        }
140    }