    001package net.minecraft.command;
    002
    003import java.util.Collections;
    004import java.util.HashMap;
    005import java.util.List;
    006import java.util.Map;
    007import java.util.regex.Matcher;
    008import java.util.regex.Pattern;
    009import net.minecraft.entity.player.EntityPlayerMP;
    010import net.minecraft.server.MinecraftServer;
    011import net.minecraft.util.ChunkCoordinates;
    012import net.minecraft.util.MathHelper;
    013import net.minecraft.world.EnumGameType;
    014
    015public 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}