001 package net.minecraft.command;
002
003 import java.util.Collections;
004 import java.util.HashMap;
005 import java.util.List;
006 import java.util.Map;
007 import java.util.regex.Matcher;
008 import java.util.regex.Pattern;
009 import net.minecraft.entity.player.EntityPlayerMP;
010 import net.minecraft.server.MinecraftServer;
011 import net.minecraft.util.ChunkCoordinates;
012 import net.minecraft.util.MathHelper;
013 import net.minecraft.world.EnumGameType;
014
015 public class PlayerSelector
016 {
017 /**
018 * This matches the at-tokens introduced for command blocks, including their arguments, if any.
019 */
020 private static final Pattern tokenPattern = Pattern.compile("^@([parf])(?:\\[([\\w=,-]*)\\])?$");
021
022 /**
023 * This matches things like "-1,,4", and is used for getting x,y,z,range from the token's argument list.
024 */
025 private static final Pattern intListPattern = Pattern.compile("\\G(-?\\w*)(?:$|,)");
026
027 /**
028 * This matches things like "rm=4,c=2" and is used for handling named token arguments.
029 */
030 private static final Pattern keyValueListPattern = Pattern.compile("\\G(\\w{1,2})=(-?\\w+)(?:$|,)");
031
032 /**
033 * Returns the one player that matches the given at-token. Returns null if more than one player matches.
034 */
035 public static EntityPlayerMP matchOnePlayer(ICommandSender par0ICommandSender, String par1Str)
036 {
037 EntityPlayerMP[] var2 = matchPlayers(par0ICommandSender, par1Str);
038 return var2 != null && var2.length == 1 ? var2[0] : null;
039 }
040
041 /**
042 * Returns a nicely-formatted string listing the matching players.
043 */
044 public static String matchPlayersAsString(ICommandSender par0ICommandSender, String par1Str)
045 {
046 EntityPlayerMP[] var2 = matchPlayers(par0ICommandSender, par1Str);
047
048 if (var2 != null && var2.length != 0)
049 {
050 String[] var3 = new String[var2.length];
051
052 for (int var4 = 0; var4 < var3.length; ++var4)
053 {
054 var3[var4] = var2[var4].getEntityName();
055 }
056
057 return CommandBase.joinNiceString(var3);
058 }
059 else
060 {
061 return null;
062 }
063 }
064
065 /**
066 * Returns an array of all players matched by the given at-token.
067 */
068 public static EntityPlayerMP[] matchPlayers(ICommandSender par0ICommandSender, String par1Str)
069 {
070 Matcher var2 = tokenPattern.matcher(par1Str);
071
072 if (var2.matches())
073 {
074 Map var3 = getArgumentMap(var2.group(2));
075 String var4 = var2.group(1);
076 int var5 = getDefaultMinimumRange(var4);
077 int var6 = getDefaultMaximumRange(var4);
078 int var7 = getDefaultMinimumLevel(var4);
079 int var8 = getDefaultMaximumLevel(var4);
080 int var9 = getDefaultCount(var4);
081 int var10 = EnumGameType.NOT_SET.getID();
082 ChunkCoordinates var11 = par0ICommandSender.getPlayerCoordinates();
083
084 if (var3.containsKey("rm"))
085 {
086 var5 = MathHelper.parseIntWithDefault((String)var3.get("rm"), var5);
087 }
088
089 if (var3.containsKey("r"))
090 {
091 var6 = MathHelper.parseIntWithDefault((String)var3.get("r"), var6);
092 }
093
094 if (var3.containsKey("lm"))
095 {
096 var7 = MathHelper.parseIntWithDefault((String)var3.get("lm"), var7);
097 }
098
099 if (var3.containsKey("l"))
100 {
101 var8 = MathHelper.parseIntWithDefault((String)var3.get("l"), var8);
102 }
103
104 if (var3.containsKey("x"))
105 {
106 var11.posX = MathHelper.parseIntWithDefault((String)var3.get("x"), var11.posX);
107 }
108
109 if (var3.containsKey("y"))
110 {
111 var11.posY = MathHelper.parseIntWithDefault((String)var3.get("y"), var11.posY);
112 }
113
114 if (var3.containsKey("z"))
115 {
116 var11.posZ = MathHelper.parseIntWithDefault((String)var3.get("z"), var11.posZ);
117 }
118
119 if (var3.containsKey("m"))
120 {
121 var10 = MathHelper.parseIntWithDefault((String)var3.get("m"), var10);
122 }
123
124 if (var3.containsKey("c"))
125 {
126 var9 = MathHelper.parseIntWithDefault((String)var3.get("c"), var9);
127 }
128
129 List var12;
130
131 if (!var4.equals("p") && !var4.equals("a"))
132 {
133 if (!var4.equals("r"))
134 {
135 return null;
136 }
137 else
138 {
139 var12 = MinecraftServer.getServer().getConfigurationManager().findPlayers(var11, var5, var6, 0, var10, var7, var8);
140 Collections.shuffle(var12);
141 var12 = var12.subList(0, Math.min(var9, var12.size()));
142 return var12 != null && !var12.isEmpty() ? (EntityPlayerMP[])var12.toArray(new EntityPlayerMP[0]) : new EntityPlayerMP[0];
143 }
144 }
145 else
146 {
147 var12 = MinecraftServer.getServer().getConfigurationManager().findPlayers(var11, var5, var6, var9, var10, var7, var8);
148 return var12 != null && !var12.isEmpty() ? (EntityPlayerMP[])var12.toArray(new EntityPlayerMP[0]) : new EntityPlayerMP[0];
149 }
150 }
151 else
152 {
153 return null;
154 }
155 }
156
157 /**
158 * Returns whether the given pattern can match more than one player.
159 */
160 public static boolean matchesMultiplePlayers(String par0Str)
161 {
162 Matcher var1 = tokenPattern.matcher(par0Str);
163
164 if (var1.matches())
165 {
166 Map var2 = getArgumentMap(var1.group(2));
167 String var3 = var1.group(1);
168 int var4 = getDefaultCount(var3);
169
170 if (var2.containsKey("c"))
171 {
172 var4 = MathHelper.parseIntWithDefault((String)var2.get("c"), var4);
173 }
174
175 return var4 != 1;
176 }
177 else
178 {
179 return false;
180 }
181 }
182
183 /**
184 * Returns whether the given token (parameter 1) has exactly the given arguments (parameter 2).
185 */
186 public static boolean hasTheseArguments(String par0Str, String par1Str)
187 {
188 Matcher var2 = tokenPattern.matcher(par0Str);
189
190 if (!var2.matches())
191 {
192 return false;
193 }
194 else
195 {
196 String var3 = var2.group(1);
197 return par1Str == null || par1Str.equals(var3);
198 }
199 }
200
201 /**
202 * Returns whether the given token has any arguments set.
203 */
204 public static boolean hasArguments(String par0Str)
205 {
206 return hasTheseArguments(par0Str, (String)null);
207 }
208
209 /**
210 * Gets the default minimum range (argument rm).
211 */
212 private static final int getDefaultMinimumRange(String par0Str)
213 {
214 return 0;
215 }
216
217 /**
218 * Gets the default maximum range (argument r).
219 */
220 private static final int getDefaultMaximumRange(String par0Str)
221 {
222 return 0;
223 }
224
225 /**
226 * Gets the default maximum experience level (argument l)
227 */
228 private static final int getDefaultMaximumLevel(String par0Str)
229 {
230 return Integer.MAX_VALUE;
231 }
232
233 /**
234 * Gets the default minimum experience level (argument lm)
235 */
236 private static final int getDefaultMinimumLevel(String par0Str)
237 {
238 return 0;
239 }
240
241 /**
242 * Gets the default number of players to return (argument c, 0 for infinite)
243 */
244 private static final int getDefaultCount(String par0Str)
245 {
246 return par0Str.equals("a") ? 0 : 1;
247 }
248
249 /**
250 * Parses the given argument string, turning it into a HashMap<String, String> of name->value.
251 */
252 private static Map getArgumentMap(String par0Str)
253 {
254 HashMap var1 = new HashMap();
255
256 if (par0Str == null)
257 {
258 return var1;
259 }
260 else
261 {
262 Matcher var2 = intListPattern.matcher(par0Str);
263 int var3 = 0;
264 int var4;
265
266 for (var4 = -1; var2.find(); var4 = var2.end())
267 {
268 String var5 = null;
269
270 switch (var3++)
271 {
272 case 0:
273 var5 = "x";
274 break;
275 case 1:
276 var5 = "y";
277 break;
278 case 2:
279 var5 = "z";
280 break;
281 case 3:
282 var5 = "r";
283 }
284
285 if (var5 != null && var2.group(1).length() > 0)
286 {
287 var1.put(var5, var2.group(1));
288 }
289 }
290
291 if (var4 < par0Str.length())
292 {
293 var2 = keyValueListPattern.matcher(var4 == -1 ? par0Str : par0Str.substring(var4));
294
295 while (var2.find())
296 {
297 var1.put(var2.group(1), var2.group(2));
298 }
299 }
300
301 return var1;
302 }
303 }
304 }