Selector parsing

I’m using the lower level command API. I’m receiving “@p” as an argument to one of my commands, executed via a command block and I’d like to parse it to the nearest player. I’m using:

Set<Entity> entities = Selector.parse(value).resolve(commandSource);

The returned entities are players, but they’re not sorted to nearest player. How should I go about parsing these selectors? Thanks.

First of all, why are you using the lower level API?
Second, Sets are unordered.

Vector3i v = ((LocatedSource) commandSource).getLocation().getPosition();
Set<Entity> entities = Selector.parse(value).resolve(commandSource);
List<Entity> sortedEntities = Collections.sort(Lists.newArrayList(entities),
    Comparator.comparing(e -> v.sub(e.getLocation().getPosition()).abs()));

Then it’s a potential improvement to the selectors API that could be made? Or maybe it should be left as it is since not everyone parsing selectors would need it to be ordered…

If they did decide to order it, should it be a random order for random selectors, and distance ordered for closest x players? What about when it’s set to all players?

Maybe leaving it as a set is best, then people who need to sort can do so.

@Kippers, is it only @p that you are receiving? I thought that generally only returned a single result unless flags were added to the selector? In that case I wouldn’t expect more then 1 entity in the set?

Mentioning @kenzierocks because your name comes up in the SelectorResolver source code.

I’m using the lower level command API because it suits my needs. I have my own annotation based command handling. How so? Do you mean selectors are automatically parsed if I use Sponge’s? If so I can check to see how they resolve it. I would guess they make use of the same Selector though.

Yeah shouldn’t have said ordered, should have said filtered.

No, @p was just an example. What I’m trying to say is that Selector.parse does not seem to behave like (I think) it should. Let me show you what I mean:

Nearest player selector @p, Kippers standing closer:
entities = {RegularImmutableSet@9738} size = 2
0 = {EntityPlayerMP@9740} “EntityPlayerMP[‘riebie’/817, l=‘world’, x=180.13, y=77.00, z=-0.69]”
1 = {EntityPlayerMP@9741} “EntityPlayerMP[‘Kippers’/1609, l=‘world’, x=184.66, y=76.00, z=0.51]”

Nearest player selector @p, riebie standing closer:
entities = {RegularImmutableSet@9831} size = 2
0 = {EntityPlayerMP@9792} “EntityPlayerMP[‘riebie’/3376, l=‘world’, x=185.18, y=76.00, z=0.74]”
1 = {EntityPlayerMP@9833} “EntityPlayerMP[‘Kippers’/3788, l=‘world’, x=192.83, y=72.00, z=7.16]”

Random player selector @r:
entities = {RegularImmutableSet@9847} size = 2
0 = {EntityRabbit@9849} “EntityRabbit[‘Rabbit’/27, l=‘world’, x=39.12, y=73.00, z=73.30]”
1 = {EntityZombie@9850} “EntityZombie[‘Zombie’/4518, l=‘world’, x=196.50, y=44.00, z=114.50]”

Definitely usable on entities… (I used it once in a map). But it is strange that it returns a set of two entities…

Summary of target selector variables
Variable Function
@p nearest player
@r random player
@a all players
@e all entities

According to the specs on that page it should return players, if not told otherwise via type argument.

Yeah, I’m just saying the behavior isn’t entirely unexpected, just very odd.

This is odd, make an issue in the appropriate repo (I don’t remember where the selector code is) and I’ll take a look.

Selector code is in SpongeCommon

Will do, thanks