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&lt;String, String&gt; of name-&gt;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    }