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 }