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 }