aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/chrisoft
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/chrisoft')
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/BlockDataCommand.java12
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelector.java405
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorOptions.java898
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorReader.java1197
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/EntityDataCommand.java4
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/MapDumpCommand.java13
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/MapTallyCommand.java7
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/commands/argument/CEntityArgumentType.java2
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/modules/AcceptablePrices.java2
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java14
-rw-r--r--src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java4
11 files changed, 1395 insertions, 1163 deletions
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/BlockDataCommand.java b/src/main/java/org/chrisoft/trashyaddon/commands/BlockDataCommand.java
index 71915bc..11fa8a3 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/BlockDataCommand.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/BlockDataCommand.java
@@ -9,14 +9,16 @@ import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.RaycastContext;
import net.minecraft.command.CommandSource;
-import net.minecraft.nbt.NbtCompound;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.component.type.NbtComponent;
import net.minecraft.text.Text;
-import net.minecraft.util.math.Box;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
+import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.Vec3d;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
+
public class BlockDataCommand extends Command {
private final MinecraftClient mc = MinecraftClient.getInstance();
public BlockDataCommand() {
@@ -28,8 +30,8 @@ public class BlockDataCommand extends Command {
builder.executes(context -> {
double RANGE = 5;
Entity player = mc.cameraEntity;
- Vec3d rot = player.getRotationVec(mc.getTickDelta());
- Vec3d min = player.getCameraPosVec(mc.getTickDelta());
+ Vec3d rot = player.getRotationVec(1.f);
+ Vec3d min = player.getCameraPosVec(1.f);
Vec3d max = min.add(rot.multiply(RANGE));
RaycastContext rc = new RaycastContext(min, max, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, player);
BlockHitResult bh = mc.world.raycast(rc);
@@ -51,7 +53,7 @@ public class BlockDataCommand extends Command {
error("block has no block entity");
return SINGLE_SUCCESS;
}
- NbtCompound bd = be.createNbt();
+ NbtCompound bd = be.createNbt(mc.world.getRegistryManager());
info(NbtHelper.toPrettyPrintedText(bd));
return SINGLE_SUCCESS;
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelector.java b/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelector.java
index 8bfa233..9d41880 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelector.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelector.java
@@ -1,25 +1,28 @@
package org.chrisoft.trashyaddon.commands;
-import com.google.common.collect.Lists;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
-import net.minecraft.client.MinecraftClient;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.predicate.NumberRange;
+import net.minecraft.resource.featuretoggle.FeatureSet;
+import net.minecraft.server.command.ServerCommandSource;
+import net.minecraft.server.network.ServerPlayerEntity;
+import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.text.Texts;
import net.minecraft.util.TypeFilter;
+import net.minecraft.util.Util;
import net.minecraft.util.function.LazyIterationConsumer;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
@@ -27,131 +30,273 @@ import org.chrisoft.trashyaddon.mixin.ClientWorldMixin;
import org.jetbrains.annotations.Nullable;
public class CEntitySelector {
- public static final int MAX_VALUE = Integer.MAX_VALUE;
- public static final BiConsumer<Vec3d, List<? extends Entity>> ARBITRARY = (pos, entities) -> {
- };
- private static final TypeFilter<Entity, ?> PASSTHROUGH_FILTER = new TypeFilter<Entity, Entity>() {
- public Entity downcast(Entity arg) {
- return arg;
- }
-
- @Override
- public Class<? extends Entity> getBaseClass() {
- return Entity.class;
- }
- };
- private final int limit;
- private final boolean includesNonPlayers;
- private final boolean localWorldOnly;
- private final Predicate<Entity> basePredicate;
- private final NumberRange.DoubleRange distance;
- private final Function<Vec3d, Vec3d> positionOffset;
- @Nullable
- private final Box box;
- private final BiConsumer<Vec3d, List<? extends Entity>> sorter;
- private final boolean senderOnly;
- @Nullable
- private final String playerName;
- @Nullable
- private final UUID uuid;
- private final TypeFilter<Entity, ?> entityFilter;
- private final boolean usesAt;
-
- public CEntitySelector(
- int count,
- boolean includesNonPlayers,
- boolean localWorldOnly,
- Predicate<Entity> basePredicate,
- NumberRange.DoubleRange distance,
- Function<Vec3d, Vec3d> positionOffset,
- @Nullable Box box,
- BiConsumer<Vec3d, List<? extends Entity>> sorter,
- boolean senderOnly,
- @Nullable String playerName,
- @Nullable UUID uuid,
- @Nullable EntityType<?> type,
- boolean usesAt
- ) {
- this.limit = count;
- this.includesNonPlayers = includesNonPlayers;
- this.localWorldOnly = localWorldOnly;
- this.basePredicate = basePredicate;
- this.distance = distance;
- this.positionOffset = positionOffset;
- this.box = box;
- this.sorter = sorter;
- this.senderOnly = senderOnly;
- this.playerName = playerName;
- this.uuid = uuid;
- this.entityFilter = (TypeFilter<Entity, ?>)(type == null ? PASSTHROUGH_FILTER : type);
- this.usesAt = usesAt;
- }
-
- public int getLimit() {
- return this.limit;
- }
-
- public boolean includesNonPlayers() {
- return this.includesNonPlayers;
- }
-
- public boolean isSenderOnly() {
- return this.senderOnly;
- }
-
- public boolean isLocalWorldOnly() {
- return this.localWorldOnly;
- }
-
- public boolean usesAt() {
- return this.usesAt;
- }
-
- private int getAppendLimit() {
- return this.sorter == ARBITRARY ? this.limit : Integer.MAX_VALUE;
- }
-
- private Predicate<Entity> getPositionPredicate(Vec3d pos) {
- Predicate<Entity> predicate = this.basePredicate;
- if (this.box != null) {
- Box lv = this.box.offset(pos);
- predicate = predicate.and(entity -> lv.intersects(entity.getBoundingBox()));
- }
-
- if (!this.distance.isDummy()) {
- predicate = predicate.and(entity -> this.distance.testSqrt(entity.squaredDistanceTo(pos)));
- }
-
- return predicate;
- }
- public List<? extends Entity> getClientSideEntityMatches(ClientWorld cw, Vec3d sourcePos) throws CommandSyntaxException {
- Predicate<Entity> p = this.getPositionPredicate(sourcePos);
- List<Entity> ret = new ArrayList<>();
- int limit = this.getAppendLimit();
- if (this.box != null)
- cw.collectEntitiesByType(this.entityFilter, this.box.offset(sourcePos), p, ret, limit);
- else {
- ((ClientWorldMixin)cw).invokeGetEntityLookup().forEach(this.entityFilter, (e) -> {
- if (p.test(e)) {
- ret.add(e);
- if (ret.size() >= limit)
- return LazyIterationConsumer.NextIteration.ABORT;
- }
- return LazyIterationConsumer.NextIteration.CONTINUE;
- });
- }
- return ret;
- }
-
- private <T extends Entity> List<T> getEntities(Vec3d pos, List<T> entities) {
- if (entities.size() > 1) {
- this.sorter.accept(pos, entities);
- }
-
- return entities.subList(0, Math.min(this.limit, entities.size()));
- }
-
- public static Text getNames(List<? extends Entity> entities) {
- return Texts.join(entities, Entity::getDisplayName);
- }
+ public static final int MAX_VALUE = Integer.MAX_VALUE;
+ public static final BiConsumer<Vec3d, List<? extends Entity>> ARBITRARY = (pos, entities) -> {
+ };
+ private static final TypeFilter<Entity, ?> PASSTHROUGH_FILTER = new TypeFilter<Entity, Entity>() {
+ public Entity downcast(Entity arg) {
+ return arg;
+ }
+
+ @Override
+ public Class<? extends Entity> getBaseClass() {
+ return Entity.class;
+ }
+ };
+ private final int limit;
+ private final boolean includesNonPlayers;
+ private final boolean localWorldOnly;
+ private final List<Predicate<Entity>> predicates;
+ private final NumberRange.DoubleRange distance;
+ private final Function<Vec3d, Vec3d> positionOffset;
+ @Nullable
+ private final Box box;
+ private final BiConsumer<Vec3d, List<? extends Entity>> sorter;
+ private final boolean senderOnly;
+ @Nullable
+ private final String playerName;
+ @Nullable
+ private final UUID uuid;
+ private final TypeFilter<Entity, ?> entityFilter;
+ private final boolean usesAt;
+
+ public CEntitySelector(
+ int count,
+ boolean includesNonPlayers,
+ boolean localWorldOnly,
+ List<Predicate<Entity>> predicates,
+ NumberRange.DoubleRange distance,
+ Function<Vec3d, Vec3d> positionOffset,
+ @Nullable Box box,
+ BiConsumer<Vec3d, List<? extends Entity>> sorter,
+ boolean senderOnly,
+ @Nullable String playerName,
+ @Nullable UUID uuid,
+ @Nullable EntityType<?> type,
+ boolean usesAt
+ ) {
+ this.limit = count;
+ this.includesNonPlayers = includesNonPlayers;
+ this.localWorldOnly = localWorldOnly;
+ this.predicates = predicates;
+ this.distance = distance;
+ this.positionOffset = positionOffset;
+ this.box = box;
+ this.sorter = sorter;
+ this.senderOnly = senderOnly;
+ this.playerName = playerName;
+ this.uuid = uuid;
+ this.entityFilter = (TypeFilter<Entity, ?>)(type == null ? PASSTHROUGH_FILTER : type);
+ this.usesAt = usesAt;
+ }
+
+ public int getLimit() {
+ return this.limit;
+ }
+
+ public boolean includesNonPlayers() {
+ return this.includesNonPlayers;
+ }
+
+ public boolean isSenderOnly() {
+ return this.senderOnly;
+ }
+
+ public boolean isLocalWorldOnly() {
+ return this.localWorldOnly;
+ }
+
+ public boolean usesAt() {
+ return this.usesAt;
+ }
+
+ private void checkSourcePermission(ServerCommandSource source) throws CommandSyntaxException {
+ if (this.usesAt && !source.hasPermissionLevel(2)) {
+ throw EntityArgumentType.NOT_ALLOWED_EXCEPTION.create();
+ }
+ }
+
+ public Entity getEntity(ServerCommandSource source) throws CommandSyntaxException {
+ this.checkSourcePermission(source);
+ List<? extends Entity> list = this.getEntities(source);
+ if (list.isEmpty()) {
+ throw EntityArgumentType.ENTITY_NOT_FOUND_EXCEPTION.create();
+ } else if (list.size() > 1) {
+ throw EntityArgumentType.TOO_MANY_ENTITIES_EXCEPTION.create();
+ } else {
+ return list.get(0);
+ }
+ }
+
+ public List<? extends Entity> getEntities(ServerCommandSource source) throws CommandSyntaxException {
+ this.checkSourcePermission(source);
+ if (!this.includesNonPlayers) {
+ return this.getPlayers(source);
+ } else if (this.playerName != null) {
+ ServerPlayerEntity lv = source.getServer().getPlayerManager().getPlayer(this.playerName);
+ return lv == null ? List.of() : List.of(lv);
+ } else if (this.uuid != null) {
+ for (ServerWorld lv2 : source.getServer().getWorlds()) {
+ Entity lv3 = lv2.getEntity(this.uuid);
+ if (lv3 != null) {
+ if (lv3.getType().isEnabled(source.getEnabledFeatures())) {
+ return List.of(lv3);
+ }
+ break;
+ }
+ }
+
+ return List.of();
+ } else {
+ Vec3d lv4 = this.positionOffset.apply(source.getPosition());
+ Box lv5 = this.getOffsetBox(lv4);
+ if (this.senderOnly) {
+ Predicate<Entity> predicate = this.getPositionPredicate(lv4, lv5, null);
+ return source.getEntity() != null && predicate.test(source.getEntity()) ? List.of(source.getEntity()) : List.of();
+ } else {
+ Predicate<Entity> predicate = this.getPositionPredicate(lv4, lv5, source.getEnabledFeatures());
+ List<Entity> list = new ObjectArrayList();
+ if (this.isLocalWorldOnly()) {
+ this.appendEntitiesFromWorld(list, source.getWorld(), lv5, predicate);
+ } else {
+ for (ServerWorld lv6 : source.getServer().getWorlds()) {
+ this.appendEntitiesFromWorld(list, lv6, lv5, predicate);
+ }
+ }
+
+ return this.getEntities(lv4, list);
+ }
+ }
+ }
+
+ private void appendEntitiesFromWorld(List<Entity> entities, ServerWorld world, @Nullable Box box, Predicate<Entity> predicate) {
+ int i = this.getAppendLimit();
+ if (entities.size() < i) {
+ if (box != null) {
+ world.collectEntitiesByType(this.entityFilter, box, predicate, entities, i);
+ } else {
+ world.collectEntitiesByType(this.entityFilter, predicate, entities, i);
+ }
+ }
+ }
+
+ private int getAppendLimit() {
+ return this.sorter == ARBITRARY ? this.limit : Integer.MAX_VALUE;
+ }
+
+ public ServerPlayerEntity getPlayer(ServerCommandSource source) throws CommandSyntaxException {
+ this.checkSourcePermission(source);
+ List<ServerPlayerEntity> list = this.getPlayers(source);
+ if (list.size() != 1) {
+ throw EntityArgumentType.PLAYER_NOT_FOUND_EXCEPTION.create();
+ } else {
+ return list.get(0);
+ }
+ }
+
+ public List<ServerPlayerEntity> getPlayers(ServerCommandSource source) throws CommandSyntaxException {
+ this.checkSourcePermission(source);
+ if (this.playerName != null) {
+ ServerPlayerEntity lv = source.getServer().getPlayerManager().getPlayer(this.playerName);
+ return lv == null ? List.of() : List.of(lv);
+ } else if (this.uuid != null) {
+ ServerPlayerEntity lv = source.getServer().getPlayerManager().getPlayer(this.uuid);
+ return lv == null ? List.of() : List.of(lv);
+ } else {
+ Vec3d lv2 = this.positionOffset.apply(source.getPosition());
+ Box lv3 = this.getOffsetBox(lv2);
+ Predicate<Entity> predicate = this.getPositionPredicate(lv2, lv3, null);
+ if (this.senderOnly) {
+ if (source.getEntity() instanceof ServerPlayerEntity lv4 && predicate.test(lv4)) {
+ return List.of(lv4);
+ }
+
+ return List.of();
+ } else {
+ int i = this.getAppendLimit();
+ List<ServerPlayerEntity> list;
+ if (this.isLocalWorldOnly()) {
+ list = source.getWorld().getPlayers(predicate, i);
+ } else {
+ list = new ObjectArrayList();
+
+ for (ServerPlayerEntity lv5 : source.getServer().getPlayerManager().getPlayerList()) {
+ if (predicate.test(lv5)) {
+ list.add(lv5);
+ if (list.size() >= i) {
+ return list;
+ }
+ }
+ }
+ }
+
+ return this.getEntities(lv2, list);
+ }
+ }
+ }
+
+ @Nullable
+ private Box getOffsetBox(Vec3d offset) {
+ return this.box != null ? this.box.offset(offset) : null;
+ }
+
+ private Predicate<Entity> getPositionPredicate(Vec3d pos, @Nullable Box box, @Nullable FeatureSet enabledFeatures) {
+ boolean bl = enabledFeatures != null;
+ boolean bl2 = box != null;
+ boolean bl3 = !this.distance.isDummy();
+ int i = (bl ? 1 : 0) + (bl2 ? 1 : 0) + (bl3 ? 1 : 0);
+ List<Predicate<Entity>> list;
+ if (i == 0) {
+ list = this.predicates;
+ } else {
+ List<Predicate<Entity>> list2 = new ObjectArrayList(this.predicates.size() + i);
+ list2.addAll(this.predicates);
+ if (bl) {
+ list2.add(entity -> entity.getType().isEnabled(enabledFeatures));
+ }
+
+ if (bl2) {
+ list2.add(entity -> box.intersects(entity.getBoundingBox()));
+ }
+
+ if (bl3) {
+ list2.add(entity -> this.distance.testSqrt(entity.squaredDistanceTo(pos)));
+ }
+
+ list = list2;
+ }
+
+ return Util.allOf(list);
+ }
+
+ public List<? extends Entity> getClientSideEntityMatches(ClientWorld cw, Vec3d sourcePos) throws CommandSyntaxException {
+ Predicate<Entity> p = this.getPositionPredicate(sourcePos, null, null);
+ List<Entity> ret = new ArrayList<>();
+ int limit = this.getAppendLimit();
+ if (this.box != null)
+ cw.collectEntitiesByType(this.entityFilter, this.box.offset(sourcePos), p, ret, limit);
+ else {
+ ((ClientWorldMixin)cw).invokeGetEntityLookup().forEach(this.entityFilter, (e) -> {
+ if (p.test(e)) {
+ ret.add(e);
+ if (ret.size() >= limit)
+ return LazyIterationConsumer.NextIteration.ABORT;
+ }
+ return LazyIterationConsumer.NextIteration.CONTINUE;
+ });
+ }
+ return ret;
+ }
+
+ private <T extends Entity> List<T> getEntities(Vec3d pos, List<T> entities) {
+ if (entities.size() > 1) {
+ this.sorter.accept(pos, entities);
+ }
+
+ return entities.subList(0, Math.min(this.limit, entities.size()));
+ }
+
+ public static Text getNames(List<? extends Entity> entities) {
+ return Texts.join(entities, Entity::getDisplayName);
+ }
}
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorOptions.java b/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorOptions.java
index cb419f0..c49e80f 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorOptions.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorOptions.java
@@ -10,463 +10,515 @@ import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Map.Entry;
import java.util.function.Predicate;
-
-import meteordevelopment.meteorclient.utils.entity.EntityUtils;
+import net.minecraft.advancement.AdvancementEntry;
import net.minecraft.advancement.AdvancementProgress;
+import net.minecraft.advancement.PlayerAdvancementTracker;
import net.minecraft.advancement.criterion.CriterionProgress;
-import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.command.CommandSource;
-import net.minecraft.command.FloatRangeArgument;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
+import net.minecraft.loot.condition.LootCondition;
+import net.minecraft.loot.context.LootContext;
+import net.minecraft.loot.context.LootContextParameterSet;
+import net.minecraft.loot.context.LootContextParameters;
+import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.nbt.StringNbtReader;
import net.minecraft.predicate.NumberRange;
import net.minecraft.registry.Registries;
+import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
+import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.scoreboard.AbstractTeam;
import net.minecraft.scoreboard.ReadableScoreboardScore;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.ScoreboardObjective;
+import net.minecraft.server.ServerAdvancementLoader;
+import net.minecraft.server.network.ServerPlayerEntity;
+import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.GameMode;
+import net.minecraft.command.FloatRangeArgument;
public class CEntitySelectorOptions {
- private static final Map<String, CEntitySelectorOptions.SelectorOption> OPTIONS = Maps.newHashMap();
- public static final DynamicCommandExceptionType UNKNOWN_OPTION_EXCEPTION = new DynamicCommandExceptionType(
- option -> Text.stringifiedTranslatable("argument.entity.options.unknown", option)
- );
- public static final DynamicCommandExceptionType INAPPLICABLE_OPTION_EXCEPTION = new DynamicCommandExceptionType(
- option -> Text.stringifiedTranslatable("argument.entity.options.inapplicable", option)
- );
- public static final SimpleCommandExceptionType NEGATIVE_DISTANCE_EXCEPTION = new SimpleCommandExceptionType(
- Text.translatable("argument.entity.options.distance.negative")
- );
- public static final SimpleCommandExceptionType NEGATIVE_LEVEL_EXCEPTION = new SimpleCommandExceptionType(
- Text.translatable("argument.entity.options.level.negative")
- );
- public static final SimpleCommandExceptionType TOO_SMALL_LEVEL_EXCEPTION = new SimpleCommandExceptionType(
- Text.translatable("argument.entity.options.limit.toosmall")
- );
- public static final DynamicCommandExceptionType IRREVERSIBLE_SORT_EXCEPTION = new DynamicCommandExceptionType(
- sortType -> Text.stringifiedTranslatable("argument.entity.options.sort.irreversible", sortType)
- );
- public static final DynamicCommandExceptionType INVALID_MODE_EXCEPTION = new DynamicCommandExceptionType(
- gameMode -> Text.stringifiedTranslatable("argument.entity.options.mode.invalid", gameMode)
- );
- public static final DynamicCommandExceptionType INVALID_TYPE_EXCEPTION = new DynamicCommandExceptionType(
- entity -> Text.stringifiedTranslatable("argument.entity.options.type.invalid", entity)
- );
-
- private static void putOption(String id, CEntitySelectorOptions.SelectorHandler handler, Predicate<CEntitySelectorReader> condition, Text description) {
- OPTIONS.put(id, new CEntitySelectorOptions.SelectorOption(handler, condition, description));
- }
-
- public static void register() {
- if (OPTIONS.isEmpty()) {
- putOption("name", reader -> {
- int i = reader.getReader().getCursor();
- boolean bl = reader.readNegationCharacter();
- String string = reader.getReader().readString();
- if (reader.excludesName() && !bl) {
- reader.getReader().setCursor(i);
- throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), "name");
- } else {
- if (bl) {
- reader.setExcludesName(true);
- } else {
- reader.setSelectsName(true);
- }
-
- reader.setPredicate(readerx -> readerx.getName().getString().equals(string) != bl);
- }
- }, reader -> !reader.selectsName(), Text.translatable("argument.entity.options.name.description"));
- putOption("distance", reader -> {
- int i = reader.getReader().getCursor();
- NumberRange.DoubleRange lv = NumberRange.DoubleRange.parse(reader.getReader());
- if ((!lv.min().isPresent() || !(lv.min().get() < 0.0)) && (!lv.max().isPresent() || !(lv.max().get() < 0.0))) {
- reader.setDistance(lv);
- reader.setLocalWorldOnly();
- } else {
- reader.getReader().setCursor(i);
- throw NEGATIVE_DISTANCE_EXCEPTION.createWithContext(reader.getReader());
- }
- }, reader -> reader.getDistance().isDummy(), Text.translatable("argument.entity.options.distance.description"));
- putOption("level", reader -> {
- int i = reader.getReader().getCursor();
- NumberRange.IntRange lv = NumberRange.IntRange.parse(reader.getReader());
- if ((!lv.min().isPresent() || lv.min().get() >= 0) && (!lv.max().isPresent() || lv.max().get() >= 0)) {
- reader.setLevelRange(lv);
- reader.setIncludesNonPlayers(false);
- } else {
- reader.getReader().setCursor(i);
- throw NEGATIVE_LEVEL_EXCEPTION.createWithContext(reader.getReader());
- }
- }, reader -> reader.getLevelRange().isDummy(), Text.translatable("argument.entity.options.level.description"));
- putOption("x", reader -> {
- reader.setLocalWorldOnly();
- reader.setX(reader.getReader().readDouble());
- }, reader -> reader.getX() == null, Text.translatable("argument.entity.options.x.description"));
- putOption("y", reader -> {
- reader.setLocalWorldOnly();
- reader.setY(reader.getReader().readDouble());
- }, reader -> reader.getY() == null, Text.translatable("argument.entity.options.y.description"));
- putOption("z", reader -> {
- reader.setLocalWorldOnly();
- reader.setZ(reader.getReader().readDouble());
- }, reader -> reader.getZ() == null, Text.translatable("argument.entity.options.z.description"));
- putOption("dx", reader -> {
- reader.setLocalWorldOnly();
- reader.setDx(reader.getReader().readDouble());
- }, reader -> reader.getDx() == null, Text.translatable("argument.entity.options.dx.description"));
- putOption("dy", reader -> {
- reader.setLocalWorldOnly();
- reader.setDy(reader.getReader().readDouble());
- }, reader -> reader.getDy() == null, Text.translatable("argument.entity.options.dy.description"));
- putOption("dz", reader -> {
- reader.setLocalWorldOnly();
- reader.setDz(reader.getReader().readDouble());
- }, reader -> reader.getDz() == null, Text.translatable("argument.entity.options.dz.description"));
- putOption(
- "x_rotation",
- reader -> reader.setPitchRange(FloatRangeArgument.parse(reader.getReader(), true, MathHelper::wrapDegrees)),
- reader -> reader.getPitchRange() == FloatRangeArgument.ANY,
- Text.translatable("argument.entity.options.x_rotation.description")
- );
- putOption(
- "y_rotation",
- reader -> reader.setYawRange(FloatRangeArgument.parse(reader.getReader(), true, MathHelper::wrapDegrees)),
- reader -> reader.getYawRange() == FloatRangeArgument.ANY,
- Text.translatable("argument.entity.options.y_rotation.description")
- );
- putOption("limit", reader -> {
- int i = reader.getReader().getCursor();
- int j = reader.getReader().readInt();
- if (j < 1) {
- reader.getReader().setCursor(i);
- throw TOO_SMALL_LEVEL_EXCEPTION.createWithContext(reader.getReader());
- } else {
- reader.setLimit(j);
- reader.setHasLimit(true);
- }
- }, reader -> !reader.isSenderOnly() && !reader.hasLimit(), Text.translatable("argument.entity.options.limit.description"));
- putOption(
- "sort",
- reader -> {
- int i = reader.getReader().getCursor();
- String string = reader.getReader().readUnquotedString();
- reader.setSuggestionProvider(
- (builder, consumer) -> CommandSource.suggestMatching(Arrays.asList("nearest", "furthest", "random", "arbitrary"), builder)
- );
-
- reader.setSorter(switch (string) {
- case "nearest" -> CEntitySelectorReader.NEAREST;
- case "furthest" -> CEntitySelectorReader.FURTHEST;
- case "random" -> CEntitySelectorReader.RANDOM;
- case "arbitrary" -> CEntitySelector.ARBITRARY;
- default -> {
- reader.getReader().setCursor(i);
- throw IRREVERSIBLE_SORT_EXCEPTION.createWithContext(reader.getReader(), string);
- }
- });
- reader.setHasSorter(true);
- },
- reader -> !reader.isSenderOnly() && !reader.hasSorter(),
- Text.translatable("argument.entity.options.sort.description")
- );
- putOption("gamemode", reader -> {
- reader.setSuggestionProvider((builder, consumer) -> {
- String stringx = builder.getRemaining().toLowerCase(Locale.ROOT);
- boolean blx = !reader.excludesGameMode();
- boolean bl2 = true;
- if (!stringx.isEmpty()) {
- if (stringx.charAt(0) == '!') {
- blx = false;
- stringx = stringx.substring(1);
- } else {
- bl2 = false;
- }
- }
-
- for (GameMode lvx : GameMode.values()) {
- if (lvx.getName().toLowerCase(Locale.ROOT).startsWith(stringx)) {
- if (bl2) {
- builder.suggest("!" + lvx.getName());
- }
-
- if (blx) {
- builder.suggest(lvx.getName());
- }
- }
- }
-
- return builder.buildFuture();
- });
- int i = reader.getReader().getCursor();
- boolean bl = reader.readNegationCharacter();
- if (reader.excludesGameMode() && !bl) {
- reader.getReader().setCursor(i);
- throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), "gamemode");
- } else {
- String string = reader.getReader().readUnquotedString();
- GameMode lv = GameMode.byName(string, null);
- if (lv == null) {
- reader.getReader().setCursor(i);
- throw INVALID_MODE_EXCEPTION.createWithContext(reader.getReader(), string);
- } else {
- reader.setIncludesNonPlayers(false);
- reader.setPredicate(entity -> {
- if (!(entity instanceof ClientPlayerEntity)) {
- return false;
- } else {
- GameMode lvx = EntityUtils.getGameMode((ClientPlayerEntity)entity);
- return bl ? lvx != lv : lvx == lv;
- }
- });
- if (bl) {
- reader.setExcludesGameMode(true);
- } else {
- reader.setSelectsGameMode(true);
- }
- }
- }
- }, reader -> !reader.selectsGameMode(), Text.translatable("argument.entity.options.gamemode.description"));
- putOption("team", reader -> {
- boolean bl = reader.readNegationCharacter();
- String string = reader.getReader().readUnquotedString();
- reader.setPredicate(entity -> {
- if (!(entity instanceof LivingEntity)) {
- return false;
- } else {
- AbstractTeam lv = entity.getScoreboardTeam();
- String string2 = lv == null ? "" : lv.getName();
- return string2.equals(string) != bl;
- }
- });
- if (bl) {
- reader.setExcludesTeam(true);
- } else {
- reader.setSelectsTeam(true);
- }
- }, reader -> !reader.selectsTeam(), Text.translatable("argument.entity.options.team.description"));
- putOption("type", reader -> {
- reader.setSuggestionProvider((builder, consumer) -> {
- CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.getIds(), builder, String.valueOf('!'));
- CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.streamTags().map(TagKey::id), builder, "!#");
- if (!reader.excludesEntityType()) {
- CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.getIds(), builder);
- CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.streamTags().map(TagKey::id), builder, String.valueOf('#'));
- }
-
- return builder.buildFuture();
- });
- int i = reader.getReader().getCursor();
- boolean bl = reader.readNegationCharacter();
- if (reader.excludesEntityType() && !bl) {
- reader.getReader().setCursor(i);
- throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), "type");
- } else {
- if (bl) {
- reader.setExcludesEntityType();
- }
-
- if (reader.readTagCharacter()) {
- TagKey<EntityType<?>> lv = TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.fromCommandInput(reader.getReader()));
- reader.setPredicate(entity -> entity.getType().isIn(lv) != bl);
- } else {
- Identifier lv2 = Identifier.fromCommandInput(reader.getReader());
- EntityType<?> lv3 = Registries.ENTITY_TYPE.getOrEmpty(lv2).orElseThrow(() -> {
- reader.getReader().setCursor(i);
- return INVALID_TYPE_EXCEPTION.createWithContext(reader.getReader(), lv2.toString());
- });
- if (Objects.equals(EntityType.PLAYER, lv3) && !bl) {
- reader.setIncludesNonPlayers(false);
- }
-
- reader.setPredicate(entity -> Objects.equals(lv3, entity.getType()) != bl);
- if (!bl) {
- reader.setEntityType(lv3);
- }
- }
- }
- }, reader -> !reader.selectsEntityType(), Text.translatable("argument.entity.options.type.description"));
- putOption("tag", reader -> {
- boolean bl = reader.readNegationCharacter();
- String string = reader.getReader().readUnquotedString();
- reader.setPredicate(entity -> "".equals(string) ? entity.getCommandTags().isEmpty() != bl : entity.getCommandTags().contains(string) != bl);
- }, reader -> true, Text.translatable("argument.entity.options.tag.description"));
- putOption("nbt", reader -> {
- boolean bl = reader.readNegationCharacter();
- NbtCompound lv = new StringNbtReader(reader.getReader()).parseCompound();
- reader.setPredicate(entity -> {
- NbtCompound lvx = entity.writeNbt(new NbtCompound());
- if (entity instanceof ClientPlayerEntity) {
- ItemStack lv2 = ((ClientPlayerEntity)entity).getInventory().getMainHandStack();
- if (!lv2.isEmpty()) {
- lvx.put("SelectedItem", lv2.writeNbt(new NbtCompound()));
- }
- }
-
- return NbtHelper.matches(lv, lvx, true) != bl;
- });
- }, reader -> true, Text.translatable("argument.entity.options.nbt.description"));
- putOption("scores", reader -> {
- StringReader stringReader = reader.getReader();
- Map<String, NumberRange.IntRange> map = Maps.newHashMap();
- stringReader.expect('{');
- stringReader.skipWhitespace();
-
- while (stringReader.canRead() && stringReader.peek() != '}') {
- stringReader.skipWhitespace();
- String string = stringReader.readUnquotedString();
- stringReader.skipWhitespace();
- stringReader.expect('=');
- stringReader.skipWhitespace();
- NumberRange.IntRange lv = NumberRange.IntRange.parse(stringReader);
- map.put(string, lv);
- stringReader.skipWhitespace();
- if (stringReader.canRead() && stringReader.peek() == ',') {
- stringReader.skip();
- }
- }
-
- stringReader.expect('}');
- if (!map.isEmpty()) {
- reader.setPredicate(entity -> {
- Scoreboard lvx = entity.getServer().getScoreboard();
+ private static final Map<String, CEntitySelectorOptions.SelectorOption> OPTIONS = Maps.newHashMap();
+ public static final DynamicCommandExceptionType UNKNOWN_OPTION_EXCEPTION = new DynamicCommandExceptionType(
+ option -> Text.stringifiedTranslatable("argument.entity.options.unknown", option)
+ );
+ public static final DynamicCommandExceptionType INAPPLICABLE_OPTION_EXCEPTION = new DynamicCommandExceptionType(
+ option -> Text.stringifiedTranslatable("argument.entity.options.inapplicable", option)
+ );
+ public static final SimpleCommandExceptionType NEGATIVE_DISTANCE_EXCEPTION = new SimpleCommandExceptionType(
+ Text.translatable("argument.entity.options.distance.negative")
+ );
+ public static final SimpleCommandExceptionType NEGATIVE_LEVEL_EXCEPTION = new SimpleCommandExceptionType(
+ Text.translatable("argument.entity.options.level.negative")
+ );
+ public static final SimpleCommandExceptionType TOO_SMALL_LEVEL_EXCEPTION = new SimpleCommandExceptionType(
+ Text.translatable("argument.entity.options.limit.toosmall")
+ );
+ public static final DynamicCommandExceptionType IRREVERSIBLE_SORT_EXCEPTION = new DynamicCommandExceptionType(
+ sortType -> Text.stringifiedTranslatable("argument.entity.options.sort.irreversible", sortType)
+ );
+ public static final DynamicCommandExceptionType INVALID_MODE_EXCEPTION = new DynamicCommandExceptionType(
+ gameMode -> Text.stringifiedTranslatable("argument.entity.options.mode.invalid", gameMode)
+ );
+ public static final DynamicCommandExceptionType INVALID_TYPE_EXCEPTION = new DynamicCommandExceptionType(
+ entity -> Text.stringifiedTranslatable("argument.entity.options.type.invalid", entity)
+ );
+
+ private static void putOption(String id, CEntitySelectorOptions.SelectorHandler handler, Predicate<CEntitySelectorReader> condition, Text description) {
+ OPTIONS.put(id, new CEntitySelectorOptions.SelectorOption(handler, condition, description));
+ }
+
+ public static void register() {
+ if (OPTIONS.isEmpty()) {
+ putOption("name", reader -> {
+ int i = reader.getReader().getCursor();
+ boolean bl = reader.readNegationCharacter();
+ String string = reader.getReader().readString();
+ if (reader.excludesName() && !bl) {
+ reader.getReader().setCursor(i);
+ throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), "name");
+ } else {
+ if (bl) {
+ reader.setExcludesName(true);
+ } else {
+ reader.setSelectsName(true);
+ }
+
+ reader.addPredicate(entity -> entity.getName().getString().equals(string) != bl);
+ }
+ }, reader -> !reader.selectsName(), Text.translatable("argument.entity.options.name.description"));
+ putOption("distance", reader -> {
+ int i = reader.getReader().getCursor();
+ NumberRange.DoubleRange lv = NumberRange.DoubleRange.parse(reader.getReader());
+ if ((!lv.min().isPresent() || !(lv.min().get() < 0.0)) && (!lv.max().isPresent() || !(lv.max().get() < 0.0))) {
+ reader.setDistance(lv);
+ reader.setLocalWorldOnly();
+ } else {
+ reader.getReader().setCursor(i);
+ throw NEGATIVE_DISTANCE_EXCEPTION.createWithContext(reader.getReader());
+ }
+ }, reader -> reader.getDistance().isDummy(), Text.translatable("argument.entity.options.distance.description"));
+ putOption("level", reader -> {
+ int i = reader.getReader().getCursor();
+ NumberRange.IntRange lv = NumberRange.IntRange.parse(reader.getReader());
+ if ((!lv.min().isPresent() || lv.min().get() >= 0) && (!lv.max().isPresent() || lv.max().get() >= 0)) {
+ reader.setLevelRange(lv);
+ reader.setIncludesNonPlayers(false);
+ } else {
+ reader.getReader().setCursor(i);
+ throw NEGATIVE_LEVEL_EXCEPTION.createWithContext(reader.getReader());
+ }
+ }, reader -> reader.getLevelRange().isDummy(), Text.translatable("argument.entity.options.level.description"));
+ putOption("x", reader -> {
+ reader.setLocalWorldOnly();
+ reader.setX(reader.getReader().readDouble());
+ }, reader -> reader.getX() == null, Text.translatable("argument.entity.options.x.description"));
+ putOption("y", reader -> {
+ reader.setLocalWorldOnly();
+ reader.setY(reader.getReader().readDouble());
+ }, reader -> reader.getY() == null, Text.translatable("argument.entity.options.y.description"));
+ putOption("z", reader -> {
+ reader.setLocalWorldOnly();
+ reader.setZ(reader.getReader().readDouble());
+ }, reader -> reader.getZ() == null, Text.translatable("argument.entity.options.z.description"));
+ putOption("dx", reader -> {
+ reader.setLocalWorldOnly();
+ reader.setDx(reader.getReader().readDouble());
+ }, reader -> reader.getDx() == null, Text.translatable("argument.entity.options.dx.description"));
+ putOption("dy", reader -> {
+ reader.setLocalWorldOnly();
+ reader.setDy(reader.getReader().readDouble());
+ }, reader -> reader.getDy() == null, Text.translatable("argument.entity.options.dy.description"));
+ putOption("dz", reader -> {
+ reader.setLocalWorldOnly();
+ reader.setDz(reader.getReader().readDouble());
+ }, reader -> reader.getDz() == null, Text.translatable("argument.entity.options.dz.description"));
+ putOption(
+ "x_rotation",
+ reader -> reader.setPitchRange(FloatRangeArgument.parse(reader.getReader(), true, MathHelper::wrapDegrees)),
+ reader -> reader.getPitchRange() == FloatRangeArgument.ANY,
+ Text.translatable("argument.entity.options.x_rotation.description")
+ );
+ putOption(
+ "y_rotation",
+ reader -> reader.setYawRange(FloatRangeArgument.parse(reader.getReader(), true, MathHelper::wrapDegrees)),
+ reader -> reader.getYawRange() == FloatRangeArgument.ANY,
+ Text.translatable("argument.entity.options.y_rotation.description")
+ );
+ putOption("limit", reader -> {
+ int i = reader.getReader().getCursor();
+ int j = reader.getReader().readInt();
+ if (j < 1) {
+ reader.getReader().setCursor(i);
+ throw TOO_SMALL_LEVEL_EXCEPTION.createWithContext(reader.getReader());
+ } else {
+ reader.setLimit(j);
+ reader.setHasLimit(true);
+ }
+ }, reader -> !reader.isSenderOnly() && !reader.hasLimit(), Text.translatable("argument.entity.options.limit.description"));
+ putOption(
+ "sort",
+ reader -> {
+ int i = reader.getReader().getCursor();
+ String string = reader.getReader().readUnquotedString();
+ reader.setSuggestionProvider(
+ (builder, consumer) -> CommandSource.suggestMatching(Arrays.asList("nearest", "furthest", "random", "arbitrary"), builder)
+ );
+
+ reader.setSorter(switch (string) {
+ case "nearest" -> CEntitySelectorReader.NEAREST;
+ case "furthest" -> CEntitySelectorReader.FURTHEST;
+ case "random" -> CEntitySelectorReader.RANDOM;
+ case "arbitrary" -> CEntitySelector.ARBITRARY;
+ default -> {
+ reader.getReader().setCursor(i);
+ throw IRREVERSIBLE_SORT_EXCEPTION.createWithContext(reader.getReader(), string);
+ }
+ });
+ reader.setHasSorter(true);
+ },
+ reader -> !reader.isSenderOnly() && !reader.hasSorter(),
+ Text.translatable("argument.entity.options.sort.description")
+ );
+ putOption("gamemode", reader -> {
+ reader.setSuggestionProvider((builder, consumer) -> {
+ String stringx = builder.getRemaining().toLowerCase(Locale.ROOT);
+ boolean blx = !reader.excludesGameMode();
+ boolean bl2 = true;
+ if (!stringx.isEmpty()) {
+ if (stringx.charAt(0) == '!') {
+ blx = false;
+ stringx = stringx.substring(1);
+ } else {
+ bl2 = false;
+ }
+ }
- for (Entry<String, NumberRange.IntRange> entry : map.entrySet()) {
- ScoreboardObjective lv2 = lvx.getNullableObjective(entry.getKey());
- if (lv2 == null) {
- return false;
- }
+ for (GameMode lvx : GameMode.values()) {
+ if (lvx.getName().toLowerCase(Locale.ROOT).startsWith(stringx)) {
+ if (bl2) {
+ builder.suggest("!" + lvx.getName());
+ }
- ReadableScoreboardScore lv3 = lvx.getScore(entity, lv2);
- if (lv3 == null) {
+ if (blx) {
+ builder.suggest(lvx.getName());
+ }
+ }
+ }
+
+ return builder.buildFuture();
+ });
+ int i = reader.getReader().getCursor();
+ boolean bl = reader.readNegationCharacter();
+ if (reader.excludesGameMode() && !bl) {
+ reader.getReader().setCursor(i);
+ throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), "gamemode");
+ } else {
+ String string = reader.getReader().readUnquotedString();
+ GameMode lv = GameMode.byName(string, null);
+ if (lv == null) {
+ reader.getReader().setCursor(i);
+ throw INVALID_MODE_EXCEPTION.createWithContext(reader.getReader(), string);
+ } else {
+ reader.setIncludesNonPlayers(false);
+ reader.addPredicate(entity -> {
+ if (!(entity instanceof ServerPlayerEntity)) {
+ return false;
+ } else {
+ GameMode lvx = ((ServerPlayerEntity)entity).interactionManager.getGameMode();
+ return bl ? lvx != lv : lvx == lv;
+ }
+ });
+ if (bl) {
+ reader.setExcludesGameMode(true);
+ } else {
+ reader.setSelectsGameMode(true);
+ }
+ }
+ }
+ }, reader -> !reader.selectsGameMode(), Text.translatable("argument.entity.options.gamemode.description"));
+ putOption("team", reader -> {
+ boolean bl = reader.readNegationCharacter();
+ String string = reader.getReader().readUnquotedString();
+ reader.addPredicate(entity -> {
+ if (!(entity instanceof LivingEntity)) {
return false;
- }
+ } else {
+ AbstractTeam lv = entity.getScoreboardTeam();
+ String string2 = lv == null ? "" : lv.getName();
+ return string2.equals(string) != bl;
+ }
+ });
+ if (bl) {
+ reader.setExcludesTeam(true);
+ } else {
+ reader.setSelectsTeam(true);
+ }
+ }, reader -> !reader.selectsTeam(), Text.translatable("argument.entity.options.team.description"));
+ putOption("type", reader -> {
+ reader.setSuggestionProvider((builder, consumer) -> {
+ CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.getIds(), builder, String.valueOf('!'));
+ CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.streamTags().map(TagKey::id), builder, "!#");
+ if (!reader.excludesEntityType()) {
+ CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.getIds(), builder);
+ CommandSource.suggestIdentifiers(Registries.ENTITY_TYPE.streamTags().map(TagKey::id), builder, String.valueOf('#'));
+ }
+
+ return builder.buildFuture();
+ });
+ int i = reader.getReader().getCursor();
+ boolean bl = reader.readNegationCharacter();
+ if (reader.excludesEntityType() && !bl) {
+ reader.getReader().setCursor(i);
+ throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), "type");
+ } else {
+ if (bl) {
+ reader.setExcludesEntityType();
+ }
+
+ if (reader.readTagCharacter()) {
+ TagKey<EntityType<?>> lv = TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.fromCommandInput(reader.getReader()));
+ reader.addPredicate(entity -> entity.getType().isIn(lv) != bl);
+ } else {
+ Identifier lv2 = Identifier.fromCommandInput(reader.getReader());
+ EntityType<?> lv3 = Registries.ENTITY_TYPE.getOrEmpty(lv2).orElseThrow(() -> {
+ reader.getReader().setCursor(i);
+ return INVALID_TYPE_EXCEPTION.createWithContext(reader.getReader(), lv2.toString());
+ });
+ if (Objects.equals(EntityType.PLAYER, lv3) && !bl) {
+ reader.setIncludesNonPlayers(false);
+ }
- if (!entry.getValue().test(lv3.getScore())) {
- return false;
- }
- }
+ reader.addPredicate(entity -> Objects.equals(lv3, entity.getType()) != bl);
+ if (!bl) {
+ reader.setEntityType(lv3);
+ }
+ }
+ }
+ }, reader -> !reader.selectsEntityType(), Text.translatable("argument.entity.options.type.description"));
+ putOption("tag", reader -> {
+ boolean bl = reader.readNegationCharacter();
+ String string = reader.getReader().readUnquotedString();
+ reader.addPredicate(entity -> "".equals(string) ? entity.getCommandTags().isEmpty() != bl : entity.getCommandTags().contains(string) != bl);
+ }, reader -> true, Text.translatable("argument.entity.options.tag.description"));
+ putOption("nbt", reader -> {
+ boolean bl = reader.readNegationCharacter();
+ NbtCompound lv = new StringNbtReader(reader.getReader()).parseCompound();
+ reader.addPredicate(entity -> {
+ NbtCompound lvx = entity.writeNbt(new NbtCompound());
+ if (entity instanceof ServerPlayerEntity lv2) {
+ ItemStack lv3 = lv2.getInventory().getMainHandStack();
+ if (!lv3.isEmpty()) {
+ lvx.put("SelectedItem", lv3.encode(lv2.getRegistryManager()));
+ }
+ }
+
+ return NbtHelper.matches(lv, lvx, true) != bl;
+ });
+ }, reader -> true, Text.translatable("argument.entity.options.nbt.description"));
+ putOption("scores", reader -> {
+ StringReader stringReader = reader.getReader();
+ Map<String, NumberRange.IntRange> map = Maps.newHashMap();
+ stringReader.expect('{');
+ stringReader.skipWhitespace();
+
+ while (stringReader.canRead() && stringReader.peek() != '}') {
+ stringReader.skipWhitespace();
+ String string = stringReader.readUnquotedString();
+ stringReader.skipWhitespace();
+ stringReader.expect('=');
+ stringReader.skipWhitespace();
+ NumberRange.IntRange lv = NumberRange.IntRange.parse(stringReader);
+ map.put(string, lv);
+ stringReader.skipWhitespace();
+ if (stringReader.canRead() && stringReader.peek() == ',') {
+ stringReader.skip();
+ }
+ }
+
+ stringReader.expect('}');
+ if (!map.isEmpty()) {
+ reader.addPredicate(entity -> {
+ Scoreboard lvx = entity.getServer().getScoreboard();
+
+ for (Entry<String, NumberRange.IntRange> entry : map.entrySet()) {
+ ScoreboardObjective lv2 = lvx.getNullableObjective(entry.getKey());
+ if (lv2 == null) {
+ return false;
+ }
+
+ ReadableScoreboardScore lv3 = lvx.getScore(entity, lv2);
+ if (lv3 == null) {
+ return false;
+ }
+
+ if (!entry.getValue().test(lv3.getScore())) {
+ return false;
+ }
+ }
- return true;
- });
- }
+ return true;
+ });
+ }
+
+ reader.setSelectsScores(true);
+ }, reader -> !reader.selectsScores(), Text.translatable("argument.entity.options.scores.description"));
+ putOption("advancements", reader -> {
+ StringReader stringReader = reader.getReader();
+ Map<Identifier, Predicate<AdvancementProgress>> map = Maps.newHashMap();
+ stringReader.expect('{');
+ stringReader.skipWhitespace();
+
+ while (stringReader.canRead() && stringReader.peek() != '}') {
+ stringReader.skipWhitespace();
+ Identifier lv = Identifier.fromCommandInput(stringReader);
+ stringReader.skipWhitespace();
+ stringReader.expect('=');
+ stringReader.skipWhitespace();
+ if (stringReader.canRead() && stringReader.peek() == '{') {
+ Map<String, Predicate<CriterionProgress>> map2 = Maps.newHashMap();
+ stringReader.skipWhitespace();
+ stringReader.expect('{');
+ stringReader.skipWhitespace();
+
+ while (stringReader.canRead() && stringReader.peek() != '}') {
+ stringReader.skipWhitespace();
+ String string = stringReader.readUnquotedString();
+ stringReader.skipWhitespace();
+ stringReader.expect('=');
+ stringReader.skipWhitespace();
+ boolean bl = stringReader.readBoolean();
+ map2.put(string, criterionProgress -> criterionProgress.isObtained() == bl);
+ stringReader.skipWhitespace();
+ if (stringReader.canRead() && stringReader.peek() == ',') {
+ stringReader.skip();
+ }
+ }
- reader.setSelectsScores(true);
- }, reader -> !reader.selectsScores(), Text.translatable("argument.entity.options.scores.description"));
- putOption("advancements", reader -> {
- StringReader stringReader = reader.getReader();
- Map<Identifier, Predicate<AdvancementProgress>> map = Maps.newHashMap();
- stringReader.expect('{');
- stringReader.skipWhitespace();
-
- while (stringReader.canRead() && stringReader.peek() != '}') {
- stringReader.skipWhitespace();
- Identifier lv = Identifier.fromCommandInput(stringReader);
- stringReader.skipWhitespace();
- stringReader.expect('=');
- stringReader.skipWhitespace();
- if (stringReader.canRead() && stringReader.peek() == '{') {
- Map<String, Predicate<CriterionProgress>> map2 = Maps.newHashMap();
- stringReader.skipWhitespace();
- stringReader.expect('{');
- stringReader.skipWhitespace();
-
- while (stringReader.canRead() && stringReader.peek() != '}') {
- stringReader.skipWhitespace();
- String string = stringReader.readUnquotedString();
- stringReader.skipWhitespace();
- stringReader.expect('=');
- stringReader.skipWhitespace();
- boolean bl = stringReader.readBoolean();
- map2.put(string, criterionProgress -> criterionProgress.isObtained() == bl);
- stringReader.skipWhitespace();
- if (stringReader.canRead() && stringReader.peek() == ',') {
+ stringReader.skipWhitespace();
+ stringReader.expect('}');
+ stringReader.skipWhitespace();
+ map.put(lv, advancementProgress -> {
+ for (Entry<String, Predicate<CriterionProgress>> entry : map2.entrySet()) {
+ CriterionProgress lvx = advancementProgress.getCriterionProgress(entry.getKey());
+ if (lvx == null || !entry.getValue().test(lvx)) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+ } else {
+ boolean bl2 = stringReader.readBoolean();
+ map.put(lv, advancementProgress -> advancementProgress.isDone() == bl2);
+ }
+
+ stringReader.skipWhitespace();
+ if (stringReader.canRead() && stringReader.peek() == ',') {
stringReader.skip();
- }
- }
-
- stringReader.skipWhitespace();
- stringReader.expect('}');
- stringReader.skipWhitespace();
- map.put(lv, advancementProgress -> {
- for (Entry<String, Predicate<CriterionProgress>> entry : map2.entrySet()) {
- CriterionProgress lvx = advancementProgress.getCriterionProgress(entry.getKey());
- if (lvx == null || !entry.getValue().test(lvx)) {
- return false;
+ }
+ }
+
+ stringReader.expect('}');
+ if (!map.isEmpty()) {
+ reader.addPredicate(entity -> {
+ if (!(entity instanceof ServerPlayerEntity lvx)) {
+ return false;
+ } else {
+ PlayerAdvancementTracker lv2 = lvx.getAdvancementTracker();
+ ServerAdvancementLoader lv3 = lvx.getServer().getAdvancementLoader();
+
+ for (Entry<Identifier, Predicate<AdvancementProgress>> entry : map.entrySet()) {
+ AdvancementEntry lv4 = lv3.get(entry.getKey());
+ if (lv4 == null || !entry.getValue().test(lv2.getProgress(lv4))) {
+ return false;
+ }
+ }
+
+ return true;
}
- }
-
- return true;
- });
- } else {
- boolean bl2 = stringReader.readBoolean();
- map.put(lv, advancementProgress -> advancementProgress.isDone() == bl2);
- }
-
- stringReader.skipWhitespace();
- if (stringReader.canRead() && stringReader.peek() == ',') {
- stringReader.skip();
- }
+ });
+ reader.setIncludesNonPlayers(false);
+ }
+
+ reader.setSelectsAdvancements(true);
+ }, reader -> !reader.selectsAdvancements(), Text.translatable("argument.entity.options.advancements.description"));
+ putOption(
+ "predicate",
+ reader -> {
+ boolean bl = reader.readNegationCharacter();
+ RegistryKey<LootCondition> lv = RegistryKey.of(RegistryKeys.PREDICATE, Identifier.fromCommandInput(reader.getReader()));
+ reader.addPredicate(
+ entity -> {
+ if (!(entity.getWorld() instanceof ServerWorld)) {
+ return false;
+ } else {
+ ServerWorld lvx = (ServerWorld)entity.getWorld();
+ Optional<LootCondition> optional = lvx.getServer()
+ .getReloadableRegistries()
+ .createRegistryLookup()
+ .getOptionalEntry(RegistryKeys.PREDICATE, lv)
+ .map(RegistryEntry::value);
+ if (optional.isEmpty()) {
+ return false;
+ } else {
+ LootContextParameterSet lv2 = new LootContextParameterSet.Builder(lvx)
+ .add(LootContextParameters.THIS_ENTITY, entity)
+ .add(LootContextParameters.ORIGIN, entity.getPos())
+ .build(LootContextTypes.SELECTOR);
+ LootContext lv3 = new LootContext.Builder(lv2).build(Optional.empty());
+ lv3.markActive(LootContext.predicate(optional.get()));
+ return bl ^ optional.get().test(lv3);
+ }
+ }
+ }
+ );
+ },
+ reader -> true,
+ Text.translatable("argument.entity.options.predicate.description")
+ );
+ }
+ }
+
+ public static CEntitySelectorOptions.SelectorHandler getHandler(CEntitySelectorReader reader, String option, int restoreCursor) throws CommandSyntaxException {
+ CEntitySelectorOptions.SelectorOption lv = OPTIONS.get(option);
+ if (lv != null) {
+ if (lv.condition.test(reader)) {
+ return lv.handler;
+ } else {
+ throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), option);
}
-
- stringReader.expect('}');
- if (!map.isEmpty()) {
- reader.setPredicate(entity -> false); // no support
- reader.setIncludesNonPlayers(false);
+ } else {
+ reader.getReader().setCursor(restoreCursor);
+ throw UNKNOWN_OPTION_EXCEPTION.createWithContext(reader.getReader(), option);
+ }
+ }
+
+ public static void suggestOptions(CEntitySelectorReader reader, SuggestionsBuilder suggestionBuilder) {
+ String string = suggestionBuilder.getRemaining().toLowerCase(Locale.ROOT);
+
+ for (Entry<String, CEntitySelectorOptions.SelectorOption> entry : OPTIONS.entrySet()) {
+ if (entry.getValue().condition.test(reader) && entry.getKey().toLowerCase(Locale.ROOT).startsWith(string)) {
+ suggestionBuilder.suggest(entry.getKey() + "=", entry.getValue().description);
}
+ }
+ }
+
+ public interface SelectorHandler {
+ void handle(CEntitySelectorReader reader) throws CommandSyntaxException;
+ }
- reader.setSelectsAdvancements(true);
- }, reader -> !reader.selectsAdvancements(), Text.translatable("argument.entity.options.advancements.description"));
- putOption(
- "predicate",
- reader -> {
- reader.setPredicate(entity -> false); // no support
- },
- reader -> true,
- Text.translatable("argument.entity.options.predicate.description")
- );
- }
- }
-
- public static CEntitySelectorOptions.SelectorHandler getHandler(CEntitySelectorReader reader, String option, int restoreCursor) throws CommandSyntaxException {
- CEntitySelectorOptions.SelectorOption lv = OPTIONS.get(option);
- if (lv != null) {
- if (lv.condition.test(reader)) {
- return lv.handler;
- } else {
- throw INAPPLICABLE_OPTION_EXCEPTION.createWithContext(reader.getReader(), option);
- }
- } else {
- reader.getReader().setCursor(restoreCursor);
- throw UNKNOWN_OPTION_EXCEPTION.createWithContext(reader.getReader(), option);
- }
- }
-
- public static void suggestOptions(CEntitySelectorReader reader, SuggestionsBuilder suggestionBuilder) {
- String string = suggestionBuilder.getRemaining().toLowerCase(Locale.ROOT);
-
- for (Entry<String, CEntitySelectorOptions.SelectorOption> entry : OPTIONS.entrySet()) {
- if (entry.getValue().condition.test(reader) && entry.getKey().toLowerCase(Locale.ROOT).startsWith(string)) {
- suggestionBuilder.suggest(entry.getKey() + "=", entry.getValue().description);
- }
- }
- }
-
- public interface SelectorHandler {
- void handle(CEntitySelectorReader reader) throws CommandSyntaxException;
- }
-
- static record SelectorOption(CEntitySelectorOptions.SelectorHandler handler, Predicate<CEntitySelectorReader> condition, Text description) {
- }
+ static record SelectorOption(CEntitySelectorOptions.SelectorHandler handler, Predicate<CEntitySelectorReader> condition, Text description) {
+ }
}
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorReader.java b/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorReader.java
index c978d6e..14c4b7a 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorReader.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/CEntitySelectorReader.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@@ -17,610 +18,634 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.ToDoubleFunction;
-
-import net.minecraft.command.FloatRangeArgument;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.predicate.NumberRange;
+import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
+import net.minecraft.command.FloatRangeArgument;
import org.jetbrains.annotations.Nullable;
public class CEntitySelectorReader {
- public static final char SELECTOR_PREFIX = '@';
- private static final char ARGUMENTS_OPENING = '[';
- private static final char ARGUMENTS_CLOSING = ']';
- public static final char ARGUMENT_DEFINER = '=';
- private static final char ARGUMENT_SEPARATOR = ',';
- public static final char INVERT_MODIFIER = '!';
- public static final char TAG_MODIFIER = '#';
- private static final char NEAREST_PLAYER = 'p';
- private static final char ALL_PLAYERS = 'a';
- private static final char RANDOM_PLAYER = 'r';
- private static final char SELF = 's';
- private static final char ALL_ENTITIES = 'e';
- public static final SimpleCommandExceptionType INVALID_ENTITY_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.entity.invalid"));
- public static final DynamicCommandExceptionType UNKNOWN_SELECTOR_EXCEPTION = new DynamicCommandExceptionType(
- selectorType -> Text.stringifiedTranslatable("argument.entity.selector.unknown", selectorType)
- );
- public static final SimpleCommandExceptionType NOT_ALLOWED_EXCEPTION = new SimpleCommandExceptionType(
- Text.translatable("argument.entity.selector.not_allowed")
- );
- public static final SimpleCommandExceptionType MISSING_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.entity.selector.missing"));
- public static final SimpleCommandExceptionType UNTERMINATED_EXCEPTION = new SimpleCommandExceptionType(
- Text.translatable("argument.entity.options.unterminated")
- );
- public static final DynamicCommandExceptionType VALUELESS_EXCEPTION = new DynamicCommandExceptionType(
- option -> Text.stringifiedTranslatable("argument.entity.options.valueless", option)
- );
- public static final BiConsumer<Vec3d, List<? extends Entity>> NEAREST = (pos, entities) -> entities.sort(
- (entity1, entity2) -> Doubles.compare(entity1.squaredDistanceTo(pos), entity2.squaredDistanceTo(pos))
- );
- public static final BiConsumer<Vec3d, List<? extends Entity>> FURTHEST = (pos, entities) -> entities.sort(
- (entity1, entity2) -> Doubles.compare(entity2.squaredDistanceTo(pos), entity1.squaredDistanceTo(pos))
- );
- public static final BiConsumer<Vec3d, List<? extends Entity>> RANDOM = (pos, entities) -> Collections.shuffle(entities);
- public static final BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> DEFAULT_SUGGESTION_PROVIDER = (builder, consumer) -> builder.buildFuture();
- private final StringReader reader;
- private final boolean atAllowed;
- private int limit;
- private boolean includesNonPlayers;
- private boolean localWorldOnly;
- private NumberRange.DoubleRange distance = NumberRange.DoubleRange.ANY;
- private NumberRange.IntRange levelRange = NumberRange.IntRange.ANY;
- @Nullable
- private Double x;
- @Nullable
- private Double y;
- @Nullable
- private Double z;
- @Nullable
- private Double dx;
- @Nullable
- private Double dy;
- @Nullable
- private Double dz;
- private FloatRangeArgument pitchRange = FloatRangeArgument.ANY;
- private FloatRangeArgument yawRange = FloatRangeArgument.ANY;
- private Predicate<Entity> predicate = entity -> true;
- private BiConsumer<Vec3d, List<? extends Entity>> sorter = CEntitySelector.ARBITRARY;
- private boolean senderOnly;
- @Nullable
- private String playerName;
- private int startCursor;
- @Nullable
- private UUID uuid;
- private BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> suggestionProvider = DEFAULT_SUGGESTION_PROVIDER;
- private boolean selectsName;
- private boolean excludesName;
- private boolean hasLimit;
- private boolean hasSorter;
- private boolean selectsGameMode;
- private boolean excludesGameMode;
- private boolean selectsTeam;
- private boolean excludesTeam;
- @Nullable
- private EntityType<?> entityType;
- private boolean excludesEntityType;
- private boolean selectsScores;
- private boolean selectsAdvancements;
- private boolean usesAt;
-
- public CEntitySelectorReader(StringReader reader) {
- this(reader, true);
- }
-
- public CEntitySelectorReader(StringReader reader, boolean atAllowed) {
- this.reader = reader;
- this.atAllowed = atAllowed;
- }
-
- public CEntitySelector build() {
- Box lv;
- if (this.dx == null && this.dy == null && this.dz == null) {
- if (this.distance.max().isPresent()) {
- double d = this.distance.max().get();
- lv = new Box(-d, -d, -d, d + 1.0, d + 1.0, d + 1.0);
- } else {
- lv = null;
- }
- } else {
- lv = this.createBox(this.dx == null ? 0.0 : this.dx, this.dy == null ? 0.0 : this.dy, this.dz == null ? 0.0 : this.dz);
- }
-
- Function<Vec3d, Vec3d> function;
- if (this.x == null && this.y == null && this.z == null) {
- function = pos -> pos;
- } else {
- function = pos -> new Vec3d(this.x == null ? pos.x : this.x, this.y == null ? pos.y : this.y, this.z == null ? pos.z : this.z);
- }
-
- return new CEntitySelector(
- this.limit,
- this.includesNonPlayers,
- this.localWorldOnly,
- this.predicate,
- this.distance,
- function,
- lv,
- this.sorter,
- this.senderOnly,
- this.playerName,
- this.uuid,
- this.entityType,
- this.usesAt
- );
- }
-
- private Box createBox(double x, double y, double z) {
- boolean bl = x < 0.0;
- boolean bl2 = y < 0.0;
- boolean bl3 = z < 0.0;
- double g = bl ? x : 0.0;
- double h = bl2 ? y : 0.0;
- double i = bl3 ? z : 0.0;
- double j = (bl ? 0.0 : x) + 1.0;
- double k = (bl2 ? 0.0 : y) + 1.0;
- double l = (bl3 ? 0.0 : z) + 1.0;
- return new Box(g, h, i, j, k, l);
- }
-
- private void buildPredicate() {
- if (this.pitchRange != FloatRangeArgument.ANY) {
- this.predicate = this.predicate.and(this.rotationPredicate(this.pitchRange, Entity::getPitch));
- }
-
- if (this.yawRange != FloatRangeArgument.ANY) {
- this.predicate = this.predicate.and(this.rotationPredicate(this.yawRange, Entity::getYaw));
- }
-
- if (!this.levelRange.isDummy()) {
- this.predicate = this.predicate
- .and(entity -> false); // no support for the xp predicate
- }
- }
-
- private Predicate<Entity> rotationPredicate(FloatRangeArgument angleRange, ToDoubleFunction<Entity> entityToAngle) {
- double d = (double)MathHelper.wrapDegrees(angleRange.min() == null ? 0.0F : angleRange.min());
- double e = (double)MathHelper.wrapDegrees(angleRange.max() == null ? 359.0F : angleRange.max());
- return entity -> {
- double f = MathHelper.wrapDegrees(entityToAngle.applyAsDouble(entity));
- return d > e ? f >= d || f <= e : f >= d && f <= e;
- };
- }
-
- protected void readAtVariable() throws CommandSyntaxException {
- this.usesAt = true;
- this.suggestionProvider = this::suggestSelectorRest;
- if (!this.reader.canRead()) {
- throw MISSING_EXCEPTION.createWithContext(this.reader);
- } else {
- int i = this.reader.getCursor();
- char c = this.reader.read();
- if (c == 'p') {
- this.limit = 1;
- this.includesNonPlayers = false;
- this.sorter = NEAREST;
- this.setEntityType(EntityType.PLAYER);
- } else if (c == 'a') {
- this.limit = Integer.MAX_VALUE;
- this.includesNonPlayers = false;
- this.sorter = CEntitySelector.ARBITRARY;
- this.setEntityType(EntityType.PLAYER);
- } else if (c == 'r') {
- this.limit = 1;
- this.includesNonPlayers = false;
- this.sorter = RANDOM;
- this.setEntityType(EntityType.PLAYER);
- } else if (c == 's') {
- this.limit = 1;
- this.includesNonPlayers = true;
- this.senderOnly = true;
- } else {
- if (c != 'e') {
- this.reader.setCursor(i);
- throw UNKNOWN_SELECTOR_EXCEPTION.createWithContext(this.reader, "@" + c);
+ public static final char SELECTOR_PREFIX = '@';
+ private static final char ARGUMENTS_OPENING = '[';
+ private static final char ARGUMENTS_CLOSING = ']';
+ public static final char ARGUMENT_DEFINER = '=';
+ private static final char ARGUMENT_SEPARATOR = ',';
+ public static final char INVERT_MODIFIER = '!';
+ public static final char TAG_MODIFIER = '#';
+ private static final char NEAREST_PLAYER = 'p';
+ private static final char ALL_PLAYERS = 'a';
+ private static final char RANDOM_PLAYER = 'r';
+ private static final char SELF = 's';
+ private static final char ALL_ENTITIES = 'e';
+ private static final char NEAREST_ENTITY = 'n';
+ public static final SimpleCommandExceptionType INVALID_ENTITY_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.entity.invalid"));
+ public static final DynamicCommandExceptionType UNKNOWN_SELECTOR_EXCEPTION = new DynamicCommandExceptionType(
+ selectorType -> Text.stringifiedTranslatable("argument.entity.selector.unknown", selectorType)
+ );
+ public static final SimpleCommandExceptionType NOT_ALLOWED_EXCEPTION = new SimpleCommandExceptionType(
+ Text.translatable("argument.entity.selector.not_allowed")
+ );
+ public static final SimpleCommandExceptionType MISSING_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.entity.selector.missing"));
+ public static final SimpleCommandExceptionType UNTERMINATED_EXCEPTION = new SimpleCommandExceptionType(
+ Text.translatable("argument.entity.options.unterminated")
+ );
+ public static final DynamicCommandExceptionType VALUELESS_EXCEPTION = new DynamicCommandExceptionType(
+ option -> Text.stringifiedTranslatable("argument.entity.options.valueless", option)
+ );
+ public static final BiConsumer<Vec3d, List<? extends Entity>> NEAREST = (pos, entities) -> entities.sort(
+ (entity1, entity2) -> Doubles.compare(entity1.squaredDistanceTo(pos), entity2.squaredDistanceTo(pos))
+ );
+ public static final BiConsumer<Vec3d, List<? extends Entity>> FURTHEST = (pos, entities) -> entities.sort(
+ (entity1, entity2) -> Doubles.compare(entity2.squaredDistanceTo(pos), entity1.squaredDistanceTo(pos))
+ );
+ public static final BiConsumer<Vec3d, List<? extends Entity>> RANDOM = (pos, entities) -> Collections.shuffle(entities);
+ public static final BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> DEFAULT_SUGGESTION_PROVIDER = (builder, consumer) -> builder.buildFuture();
+ private final StringReader reader;
+ private final boolean atAllowed;
+ private int limit;
+ private boolean includesNonPlayers;
+ private boolean localWorldOnly;
+ private NumberRange.DoubleRange distance = NumberRange.DoubleRange.ANY;
+ private NumberRange.IntRange levelRange = NumberRange.IntRange.ANY;
+ @Nullable
+ private Double x;
+ @Nullable
+ private Double y;
+ @Nullable
+ private Double z;
+ @Nullable
+ private Double dx;
+ @Nullable
+ private Double dy;
+ @Nullable
+ private Double dz;
+ private FloatRangeArgument pitchRange = FloatRangeArgument.ANY;
+ private FloatRangeArgument yawRange = FloatRangeArgument.ANY;
+ private final List<Predicate<Entity>> predicates = new ArrayList<>();
+ private BiConsumer<Vec3d, List<? extends Entity>> sorter = CEntitySelector.ARBITRARY;
+ private boolean senderOnly;
+ @Nullable
+ private String playerName;
+ private int startCursor;
+ @Nullable
+ private UUID uuid;
+ private BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> suggestionProvider = DEFAULT_SUGGESTION_PROVIDER;
+ private boolean selectsName;
+ private boolean excludesName;
+ private boolean hasLimit;
+ private boolean hasSorter;
+ private boolean selectsGameMode;
+ private boolean excludesGameMode;
+ private boolean selectsTeam;
+ private boolean excludesTeam;
+ @Nullable
+ private EntityType<?> entityType;
+ private boolean excludesEntityType;
+ private boolean selectsScores;
+ private boolean selectsAdvancements;
+ private boolean usesAt;
+
+ public CEntitySelectorReader(StringReader reader, boolean atAllowed) {
+ this.reader = reader;
+ this.atAllowed = atAllowed;
+ }
+
+ public static <S> boolean shouldAllowAtSelectors(S source) {
+ /*if (source instanceof CommandSource lv && lv.hasPermissionLevel(2)) {
+ return true;
+ }
+
+ return false;*/
+ return true;
+ }
+
+ public CEntitySelector build() {
+ Box lv;
+ if (this.dx == null && this.dy == null && this.dz == null) {
+ if (this.distance.max().isPresent()) {
+ double d = this.distance.max().get();
+ lv = new Box(-d, -d, -d, d + 1.0, d + 1.0, d + 1.0);
+ } else {
+ lv = null;
+ }
+ } else {
+ lv = this.createBox(this.dx == null ? 0.0 : this.dx, this.dy == null ? 0.0 : this.dy, this.dz == null ? 0.0 : this.dz);
+ }
+
+ Function<Vec3d, Vec3d> function;
+ if (this.x == null && this.y == null && this.z == null) {
+ function = pos -> pos;
+ } else {
+ function = pos -> new Vec3d(this.x == null ? pos.x : this.x, this.y == null ? pos.y : this.y, this.z == null ? pos.z : this.z);
+ }
+
+ return new CEntitySelector(
+ this.limit,
+ this.includesNonPlayers,
+ this.localWorldOnly,
+ List.copyOf(this.predicates),
+ this.distance,
+ function,
+ lv,
+ this.sorter,
+ this.senderOnly,
+ this.playerName,
+ this.uuid,
+ this.entityType,
+ this.usesAt
+ );
+ }
+
+ private Box createBox(double x, double y, double z) {
+ boolean bl = x < 0.0;
+ boolean bl2 = y < 0.0;
+ boolean bl3 = z < 0.0;
+ double g = bl ? x : 0.0;
+ double h = bl2 ? y : 0.0;
+ double i = bl3 ? z : 0.0;
+ double j = (bl ? 0.0 : x) + 1.0;
+ double k = (bl2 ? 0.0 : y) + 1.0;
+ double l = (bl3 ? 0.0 : z) + 1.0;
+ return new Box(g, h, i, j, k, l);
+ }
+
+ private void buildPredicate() {
+ if (this.pitchRange != FloatRangeArgument.ANY) {
+ this.predicates.add(this.rotationPredicate(this.pitchRange, Entity::getPitch));
+ }
+
+ if (this.yawRange != FloatRangeArgument.ANY) {
+ this.predicates.add(this.rotationPredicate(this.yawRange, Entity::getYaw));
+ }
+
+ if (!this.levelRange.isDummy()) {
+ this.predicates.add(entity -> !(entity instanceof ServerPlayerEntity) ? false : this.levelRange.test(((ServerPlayerEntity)entity).experienceLevel));
+ }
+ }
+
+ private Predicate<Entity> rotationPredicate(FloatRangeArgument angleRange, ToDoubleFunction<Entity> entityToAngle) {
+ double d = (double)MathHelper.wrapDegrees(angleRange.min() == null ? 0.0F : angleRange.min());
+ double e = (double)MathHelper.wrapDegrees(angleRange.max() == null ? 359.0F : angleRange.max());
+ return entity -> {
+ double f = MathHelper.wrapDegrees(entityToAngle.applyAsDouble(entity));
+ return d > e ? f >= d || f <= e : f >= d && f <= e;
+ };
+ }
+
+ protected void readAtVariable() throws CommandSyntaxException {
+ this.usesAt = true;
+ this.suggestionProvider = this::suggestSelectorRest;
+ if (!this.reader.canRead()) {
+ throw MISSING_EXCEPTION.createWithContext(this.reader);
+ } else {
+ int i = this.reader.getCursor();
+ char c = this.reader.read();
+
+ if (switch (c) {
+ case 'a' -> {
+ this.limit = Integer.MAX_VALUE;
+ this.includesNonPlayers = false;
+ this.sorter = CEntitySelector.ARBITRARY;
+ this.setEntityType(EntityType.PLAYER);
+ yield false;
+ }
+ default -> {
+ this.reader.setCursor(i);
+ throw UNKNOWN_SELECTOR_EXCEPTION.createWithContext(this.reader, "@" + c);
+ }
+ case 'e' -> {
+ this.limit = Integer.MAX_VALUE;
+ this.includesNonPlayers = true;
+ this.sorter = CEntitySelector.ARBITRARY;
+ yield true;
+ }
+ case 'n' -> {
+ this.limit = 1;
+ this.includesNonPlayers = true;
+ this.sorter = NEAREST;
+ yield true;
+ }
+ case 'p' -> {
+ this.limit = 1;
+ this.includesNonPlayers = false;
+ this.sorter = NEAREST;
+ this.setEntityType(EntityType.PLAYER);
+ yield false;
+ }
+ case 'r' -> {
+ this.limit = 1;
+ this.includesNonPlayers = false;
+ this.sorter = RANDOM;
+ this.setEntityType(EntityType.PLAYER);
+ yield false;
+ }
+ case 's' -> {
+ this.limit = 1;
+ this.includesNonPlayers = true;
+ this.senderOnly = true;
+ yield false;
+ }
+ }) {
+ this.predicates.add(Entity::isAlive);
}
- this.limit = Integer.MAX_VALUE;
+ this.suggestionProvider = this::suggestOpen;
+ if (this.reader.canRead() && this.reader.peek() == '[') {
+ this.reader.skip();
+ this.suggestionProvider = this::suggestOptionOrEnd;
+ this.readArguments();
+ }
+ }
+ }
+
+ protected void readRegular() throws CommandSyntaxException {
+ if (this.reader.canRead()) {
+ this.suggestionProvider = this::suggestNormal;
+ }
+
+ int i = this.reader.getCursor();
+ String string = this.reader.readString();
+
+ try {
+ this.uuid = UUID.fromString(string);
this.includesNonPlayers = true;
- this.sorter = CEntitySelector.ARBITRARY;
- this.predicate = Entity::isAlive;
- }
+ } catch (IllegalArgumentException var4) {
+ if (string.isEmpty() || string.length() > 16) {
+ this.reader.setCursor(i);
+ throw INVALID_ENTITY_EXCEPTION.createWithContext(this.reader);
+ }
+
+ this.includesNonPlayers = false;
+ this.playerName = string;
+ }
+
+ this.limit = 1;
+ }
+
+ protected void readArguments() throws CommandSyntaxException {
+ this.suggestionProvider = this::suggestOption;
+ this.reader.skipWhitespace();
+
+ while (this.reader.canRead() && this.reader.peek() != ']') {
+ this.reader.skipWhitespace();
+ int i = this.reader.getCursor();
+ String string = this.reader.readString();
+ CEntitySelectorOptions.SelectorHandler lv = CEntitySelectorOptions.getHandler(this, string, i);
+ this.reader.skipWhitespace();
+ if (!this.reader.canRead() || this.reader.peek() != '=') {
+ this.reader.setCursor(i);
+ throw VALUELESS_EXCEPTION.createWithContext(this.reader, string);
+ }
- this.suggestionProvider = this::suggestOpen;
- if (this.reader.canRead() && this.reader.peek() == '[') {
this.reader.skip();
- this.suggestionProvider = this::suggestOptionOrEnd;
- this.readArguments();
- }
- }
- }
-
- protected void readRegular() throws CommandSyntaxException {
- if (this.reader.canRead()) {
- this.suggestionProvider = this::suggestNormal;
- }
-
- int i = this.reader.getCursor();
- String string = this.reader.readString();
-
- try {
- this.uuid = UUID.fromString(string);
- this.includesNonPlayers = true;
- } catch (IllegalArgumentException var4) {
- if (string.isEmpty() || string.length() > 16) {
- this.reader.setCursor(i);
- throw INVALID_ENTITY_EXCEPTION.createWithContext(this.reader);
- }
-
- this.includesNonPlayers = false;
- this.playerName = string;
- }
-
- this.limit = 1;
- }
-
- protected void readArguments() throws CommandSyntaxException {
- this.suggestionProvider = this::suggestOption;
- this.reader.skipWhitespace();
-
- while (this.reader.canRead() && this.reader.peek() != ']') {
- this.reader.skipWhitespace();
- int i = this.reader.getCursor();
- String string = this.reader.readString();
- CEntitySelectorOptions.SelectorHandler lv = CEntitySelectorOptions.getHandler(this, string, i);
- this.reader.skipWhitespace();
- if (!this.reader.canRead() || this.reader.peek() != '=') {
- this.reader.setCursor(i);
- throw VALUELESS_EXCEPTION.createWithContext(this.reader, string);
- }
-
- this.reader.skip();
- this.reader.skipWhitespace();
- this.suggestionProvider = DEFAULT_SUGGESTION_PROVIDER;
- lv.handle(this);
- this.reader.skipWhitespace();
- this.suggestionProvider = this::suggestEndNext;
- if (this.reader.canRead()) {
- if (this.reader.peek() != ',') {
- if (this.reader.peek() != ']') {
- throw UNTERMINATED_EXCEPTION.createWithContext(this.reader);
- }
- break;
+ this.reader.skipWhitespace();
+ this.suggestionProvider = DEFAULT_SUGGESTION_PROVIDER;
+ lv.handle(this);
+ this.reader.skipWhitespace();
+ this.suggestionProvider = this::suggestEndNext;
+ if (this.reader.canRead()) {
+ if (this.reader.peek() != ',') {
+ if (this.reader.peek() != ']') {
+ throw UNTERMINATED_EXCEPTION.createWithContext(this.reader);
+ }
+ break;
+ }
+
+ this.reader.skip();
+ this.suggestionProvider = this::suggestOption;
+ }
+ }
+
+ if (this.reader.canRead()) {
+ this.reader.skip();
+ this.suggestionProvider = DEFAULT_SUGGESTION_PROVIDER;
+ } else {
+ throw UNTERMINATED_EXCEPTION.createWithContext(this.reader);
+ }
+ }
+
+ public boolean readNegationCharacter() {
+ this.reader.skipWhitespace();
+ if (this.reader.canRead() && this.reader.peek() == '!') {
+ this.reader.skip();
+ this.reader.skipWhitespace();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean readTagCharacter() {
+ this.reader.skipWhitespace();
+ if (this.reader.canRead() && this.reader.peek() == '#') {
+ this.reader.skip();
+ this.reader.skipWhitespace();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public StringReader getReader() {
+ return this.reader;
+ }
+
+ public void addPredicate(Predicate<Entity> predicate) {
+ this.predicates.add(predicate);
+ }
+
+ public void setLocalWorldOnly() {
+ this.localWorldOnly = true;
+ }
+
+ public NumberRange.DoubleRange getDistance() {
+ return this.distance;
+ }
+
+ public void setDistance(NumberRange.DoubleRange distance) {
+ this.distance = distance;
+ }
+
+ public NumberRange.IntRange getLevelRange() {
+ return this.levelRange;
+ }
+
+ public void setLevelRange(NumberRange.IntRange levelRange) {
+ this.levelRange = levelRange;
+ }
+
+ public FloatRangeArgument getPitchRange() {
+ return this.pitchRange;
+ }
+
+ public void setPitchRange(FloatRangeArgument pitchRange) {
+ this.pitchRange = pitchRange;
+ }
+
+ public FloatRangeArgument getYawRange() {
+ return this.yawRange;
+ }
+
+ public void setYawRange(FloatRangeArgument yawRange) {
+ this.yawRange = yawRange;
+ }
+
+ @Nullable
+ public Double getX() {
+ return this.x;
+ }
+
+ @Nullable
+ public Double getY() {
+ return this.y;
+ }
+
+ @Nullable
+ public Double getZ() {
+ return this.z;
+ }
+
+ public void setX(double x) {
+ this.x = x;
+ }
+
+ public void setY(double y) {
+ this.y = y;
+ }
+
+ public void setZ(double z) {
+ this.z = z;
+ }
+
+ public void setDx(double dx) {
+ this.dx = dx;
+ }
+
+ public void setDy(double dy) {
+ this.dy = dy;
+ }
+
+ public void setDz(double dz) {
+ this.dz = dz;
+ }
+
+ @Nullable
+ public Double getDx() {
+ return this.dx;
+ }
+
+ @Nullable
+ public Double getDy() {
+ return this.dy;
+ }
+
+ @Nullable
+ public Double getDz() {
+ return this.dz;
+ }
+
+ public void setLimit(int limit) {
+ this.limit = limit;
+ }
+
+ public void setIncludesNonPlayers(boolean includesNonPlayers) {
+ this.includesNonPlayers = includesNonPlayers;
+ }
+
+ public BiConsumer<Vec3d, List<? extends Entity>> getSorter() {
+ return this.sorter;
+ }
+
+ public void setSorter(BiConsumer<Vec3d, List<? extends Entity>> sorter) {
+ this.sorter = sorter;
+ }
+
+ public CEntitySelector read() throws CommandSyntaxException {
+ this.startCursor = this.reader.getCursor();
+ this.suggestionProvider = this::suggestSelector;
+ if (this.reader.canRead() && this.reader.peek() == '@') {
+ if (!this.atAllowed) {
+ throw NOT_ALLOWED_EXCEPTION.createWithContext(this.reader);
}
this.reader.skip();
- this.suggestionProvider = this::suggestOption;
- }
- }
-
- if (this.reader.canRead()) {
- this.reader.skip();
- this.suggestionProvider = DEFAULT_SUGGESTION_PROVIDER;
- } else {
- throw UNTERMINATED_EXCEPTION.createWithContext(this.reader);
- }
- }
-
- public boolean readNegationCharacter() {
- this.reader.skipWhitespace();
- if (this.reader.canRead() && this.reader.peek() == '!') {
- this.reader.skip();
- this.reader.skipWhitespace();
- return true;
- } else {
- return false;
- }
- }
-
- public boolean readTagCharacter() {
- this.reader.skipWhitespace();
- if (this.reader.canRead() && this.reader.peek() == '#') {
- this.reader.skip();
- this.reader.skipWhitespace();
- return true;
- } else {
- return false;
- }
- }
-
- public StringReader getReader() {
- return this.reader;
- }
-
- public void setPredicate(Predicate<Entity> predicate) {
- this.predicate = this.predicate.and(predicate);
- }
-
- public void setLocalWorldOnly() {
- this.localWorldOnly = true;
- }
-
- public NumberRange.DoubleRange getDistance() {
- return this.distance;
- }
-
- public void setDistance(NumberRange.DoubleRange distance) {
- this.distance = distance;
- }
-
- public NumberRange.IntRange getLevelRange() {
- return this.levelRange;
- }
-
- public void setLevelRange(NumberRange.IntRange levelRange) {
- this.levelRange = levelRange;
- }
-
- public FloatRangeArgument getPitchRange() {
- return this.pitchRange;
- }
-
- public void setPitchRange(FloatRangeArgument pitchRange) {
- this.pitchRange = pitchRange;
- }
-
- public FloatRangeArgument getYawRange() {
- return this.yawRange;
- }
-
- public void setYawRange(FloatRangeArgument yawRange) {
- this.yawRange = yawRange;
- }
-
- @Nullable
- public Double getX() {
- return this.x;
- }
-
- @Nullable
- public Double getY() {
- return this.y;
- }
-
- @Nullable
- public Double getZ() {
- return this.z;
- }
-
- public void setX(double x) {
- this.x = x;
- }
-
- public void setY(double y) {
- this.y = y;
- }
-
- public void setZ(double z) {
- this.z = z;
- }
-
- public void setDx(double dx) {
- this.dx = dx;
- }
-
- public void setDy(double dy) {
- this.dy = dy;
- }
-
- public void setDz(double dz) {
- this.dz = dz;
- }
-
- @Nullable
- public Double getDx() {
- return this.dx;
- }
-
- @Nullable
- public Double getDy() {
- return this.dy;
- }
-
- @Nullable
- public Double getDz() {
- return this.dz;
- }
-
- public void setLimit(int limit) {
- this.limit = limit;
- }
-
- public void setIncludesNonPlayers(boolean includesNonPlayers) {
- this.includesNonPlayers = includesNonPlayers;
- }
-
- public BiConsumer<Vec3d, List<? extends Entity>> getSorter() {
- return this.sorter;
- }
-
- public void setSorter(BiConsumer<Vec3d, List<? extends Entity>> sorter) {
- this.sorter = sorter;
- }
-
- public CEntitySelector read() throws CommandSyntaxException {
- this.startCursor = this.reader.getCursor();
- this.suggestionProvider = this::suggestSelector;
- if (this.reader.canRead() && this.reader.peek() == '@') {
- if (!this.atAllowed) {
- throw NOT_ALLOWED_EXCEPTION.createWithContext(this.reader);
- }
-
- this.reader.skip();
- this.readAtVariable();
- } else {
- this.readRegular();
- }
-
- this.buildPredicate();
- return this.build();
- }
-
- private static void suggestSelector(SuggestionsBuilder builder) {
- builder.suggest("@p", Text.translatable("argument.entity.selector.nearestPlayer"));
- builder.suggest("@a", Text.translatable("argument.entity.selector.allPlayers"));
- builder.suggest("@r", Text.translatable("argument.entity.selector.randomPlayer"));
- builder.suggest("@s", Text.translatable("argument.entity.selector.self"));
- builder.suggest("@e", Text.translatable("argument.entity.selector.allEntities"));
- }
-
- private CompletableFuture<Suggestions> suggestSelector(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- consumer.accept(builder);
- if (this.atAllowed) {
- suggestSelector(builder);
- }
-
- return builder.buildFuture();
- }
-
- private CompletableFuture<Suggestions> suggestNormal(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- SuggestionsBuilder suggestionsBuilder2 = builder.createOffset(this.startCursor);
- consumer.accept(suggestionsBuilder2);
- return builder.add(suggestionsBuilder2).buildFuture();
- }
-
- private CompletableFuture<Suggestions> suggestSelectorRest(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- SuggestionsBuilder suggestionsBuilder2 = builder.createOffset(builder.getStart() - 1);
- suggestSelector(suggestionsBuilder2);
- builder.add(suggestionsBuilder2);
- return builder.buildFuture();
- }
-
- private CompletableFuture<Suggestions> suggestOpen(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- builder.suggest(String.valueOf('['));
- return builder.buildFuture();
- }
-
- private CompletableFuture<Suggestions> suggestOptionOrEnd(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- builder.suggest(String.valueOf(']'));
- CEntitySelectorOptions.suggestOptions(this, builder);
- return builder.buildFuture();
- }
-
- private CompletableFuture<Suggestions> suggestOption(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- CEntitySelectorOptions.suggestOptions(this, builder);
- return builder.buildFuture();
- }
-
- private CompletableFuture<Suggestions> suggestEndNext(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- builder.suggest(String.valueOf(','));
- builder.suggest(String.valueOf(']'));
- return builder.buildFuture();
- }
-
- private CompletableFuture<Suggestions> suggestDefinerNext(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- builder.suggest(String.valueOf('='));
- return builder.buildFuture();
- }
-
- public boolean isSenderOnly() {
- return this.senderOnly;
- }
-
- public void setSuggestionProvider(BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> suggestionProvider) {
- this.suggestionProvider = suggestionProvider;
- }
-
- public CompletableFuture<Suggestions> listSuggestions(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
- return this.suggestionProvider.apply(builder.createOffset(this.reader.getCursor()), consumer);
- }
-
- public boolean selectsName() {
- return this.selectsName;
- }
-
- public void setSelectsName(boolean selectsName) {
- this.selectsName = selectsName;
- }
-
- public boolean excludesName() {
- return this.excludesName;
- }
-
- public void setExcludesName(boolean excludesName) {
- this.excludesName = excludesName;
- }
-
- public boolean hasLimit() {
- return this.hasLimit;
- }
-
- public void setHasLimit(boolean hasLimit) {
- this.hasLimit = hasLimit;
- }
-
- public boolean hasSorter() {
- return this.hasSorter;
- }
-
- public void setHasSorter(boolean hasSorter) {
- this.hasSorter = hasSorter;
- }
-
- public boolean selectsGameMode() {
- return this.selectsGameMode;
- }
-
- public void setSelectsGameMode(boolean selectsGameMode) {
- this.selectsGameMode = selectsGameMode;
- }
-
- public boolean excludesGameMode() {
- return this.excludesGameMode;
- }
-
- public void setExcludesGameMode(boolean excludesGameMode) {
- this.excludesGameMode = excludesGameMode;
- }
-
- public boolean selectsTeam() {
- return this.selectsTeam;
- }
-
- public void setSelectsTeam(boolean selectsTeam) {
- this.selectsTeam = selectsTeam;
- }
-
- public boolean excludesTeam() {
- return this.excludesTeam;
- }
-
- public void setExcludesTeam(boolean excludesTeam) {
- this.excludesTeam = excludesTeam;
- }
-
- public void setEntityType(EntityType<?> entityType) {
- this.entityType = entityType;
- }
-
- public void setExcludesEntityType() {
- this.excludesEntityType = true;
- }
-
- public boolean selectsEntityType() {
- return this.entityType != null;
- }
-
- public boolean excludesEntityType() {
- return this.excludesEntityType;
- }
-
- public boolean selectsScores() {
- return this.selectsScores;
- }
-
- public void setSelectsScores(boolean selectsScores) {
- this.selectsScores = selectsScores;
- }
+ this.readAtVariable();
+ } else {
+ this.readRegular();
+ }
+
+ this.buildPredicate();
+ return this.build();
+ }
+
+ private static void suggestSelector(SuggestionsBuilder builder) {
+ builder.suggest("@p", Text.translatable("argument.entity.selector.nearestPlayer"));
+ builder.suggest("@a", Text.translatable("argument.entity.selector.allPlayers"));
+ builder.suggest("@r", Text.translatable("argument.entity.selector.randomPlayer"));
+ builder.suggest("@s", Text.translatable("argument.entity.selector.self"));
+ builder.suggest("@e", Text.translatable("argument.entity.selector.allEntities"));
+ builder.suggest("@n", Text.translatable("argument.entity.selector.nearestEntity"));
+ }
+
+ private CompletableFuture<Suggestions> suggestSelector(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ consumer.accept(builder);
+ if (this.atAllowed) {
+ suggestSelector(builder);
+ }
+
+ return builder.buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestNormal(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ SuggestionsBuilder suggestionsBuilder2 = builder.createOffset(this.startCursor);
+ consumer.accept(suggestionsBuilder2);
+ return builder.add(suggestionsBuilder2).buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestSelectorRest(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ SuggestionsBuilder suggestionsBuilder2 = builder.createOffset(builder.getStart() - 1);
+ suggestSelector(suggestionsBuilder2);
+ builder.add(suggestionsBuilder2);
+ return builder.buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestOpen(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ builder.suggest(String.valueOf('['));
+ return builder.buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestOptionOrEnd(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ builder.suggest(String.valueOf(']'));
+ CEntitySelectorOptions.suggestOptions(this, builder);
+ return builder.buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestOption(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ CEntitySelectorOptions.suggestOptions(this, builder);
+ return builder.buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestEndNext(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ builder.suggest(String.valueOf(','));
+ builder.suggest(String.valueOf(']'));
+ return builder.buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestDefinerNext(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ builder.suggest(String.valueOf('='));
+ return builder.buildFuture();
+ }
+
+ public boolean isSenderOnly() {
+ return this.senderOnly;
+ }
+
+ public void setSuggestionProvider(BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> suggestionProvider) {
+ this.suggestionProvider = suggestionProvider;
+ }
+
+ public CompletableFuture<Suggestions> listSuggestions(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+ return this.suggestionProvider.apply(builder.createOffset(this.reader.getCursor()), consumer);
+ }
+
+ public boolean selectsName() {
+ return this.selectsName;
+ }
+
+ public void setSelectsName(boolean selectsName) {
+ this.selectsName = selectsName;
+ }
+
+ public boolean excludesName() {
+ return this.excludesName;
+ }
+
+ public void setExcludesName(boolean excludesName) {
+ this.excludesName = excludesName;
+ }
+
+ public boolean hasLimit() {
+ return this.hasLimit;
+ }
+
+ public void setHasLimit(boolean hasLimit) {
+ this.hasLimit = hasLimit;
+ }
+
+ public boolean hasSorter() {
+ return this.hasSorter;
+ }
+
+ public void setHasSorter(boolean hasSorter) {
+ this.hasSorter = hasSorter;
+ }
+
+ public boolean selectsGameMode() {
+ return this.selectsGameMode;
+ }
+
+ public void setSelectsGameMode(boolean selectsGameMode) {
+ this.selectsGameMode = selectsGameMode;
+ }
+
+ public boolean excludesGameMode() {
+ return this.excludesGameMode;
+ }
+
+ public void setExcludesGameMode(boolean excludesGameMode) {
+ this.excludesGameMode = excludesGameMode;
+ }
+
+ public boolean selectsTeam() {
+ return this.selectsTeam;
+ }
+
+ public void setSelectsTeam(boolean selectsTeam) {
+ this.selectsTeam = selectsTeam;
+ }
+
+ public boolean excludesTeam() {
+ return this.excludesTeam;
+ }
+
+ public void setExcludesTeam(boolean excludesTeam) {
+ this.excludesTeam = excludesTeam;
+ }
+
+ public void setEntityType(EntityType<?> entityType) {
+ this.entityType = entityType;
+ }
+
+ public void setExcludesEntityType() {
+ this.excludesEntityType = true;
+ }
+
+ public boolean selectsEntityType() {
+ return this.entityType != null;
+ }
+
+ public boolean excludesEntityType() {
+ return this.excludesEntityType;
+ }
+
+ public boolean selectsScores() {
+ return this.selectsScores;
+ }
+
+ public void setSelectsScores(boolean selectsScores) {
+ this.selectsScores = selectsScores;
+ }
- public boolean selectsAdvancements() {
- return this.selectsAdvancements;
- }
+ public boolean selectsAdvancements() {
+ return this.selectsAdvancements;
+ }
- public void setSelectsAdvancements(boolean selectsAdvancements) {
- this.selectsAdvancements = selectsAdvancements;
- }
+ public void setSelectsAdvancements(boolean selectsAdvancements) {
+ this.selectsAdvancements = selectsAdvancements;
+ }
}
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/EntityDataCommand.java b/src/main/java/org/chrisoft/trashyaddon/commands/EntityDataCommand.java
index 4f88655..a6ab279 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/EntityDataCommand.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/EntityDataCommand.java
@@ -27,8 +27,8 @@ public class EntityDataCommand extends Command {
//info("erectile dysfunction start");
double RANGE = 5;
Entity player = mc.cameraEntity;
- Vec3d rot = player.getRotationVec(mc.getTickDelta());
- Vec3d min = player.getCameraPosVec(mc.getTickDelta());
+ Vec3d rot = player.getRotationVec(1.f);
+ Vec3d min = player.getCameraPosVec(1.f);
Vec3d max = min.add(rot.multiply(RANGE));
Box box = player.getBoundingBox().stretch(rot.multiply(RANGE));
EntityHitResult eh = ProjectileUtil.raycast(player, min, max, box, x -> true ,RANGE * RANGE);
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/MapDumpCommand.java b/src/main/java/org/chrisoft/trashyaddon/commands/MapDumpCommand.java
index 2bc7096..b09c9be 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/MapDumpCommand.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/MapDumpCommand.java
@@ -4,6 +4,8 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.commands.Command;
import net.minecraft.command.CommandSource;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.component.type.MapIdComponent;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.decoration.ItemFrameEntity;
import net.minecraft.client.MinecraftClient;
@@ -19,7 +21,6 @@ import java.util.zip.GZIPOutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Vector;
-import java.util.OptionalInt;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
@@ -38,14 +39,14 @@ public class MapDumpCommand extends Command {
if (e.getType() != EntityType.ITEM_FRAME && e.getType() != EntityType.GLOW_ITEM_FRAME)
continue;
ItemFrameEntity ife = (ItemFrameEntity) e;
- OptionalInt oid = ife.getMapId();
- if (oid.isEmpty())
+ MapIdComponent idc = ife.getMapId(ife.getHeldItemStack());
+ if (idc == null)
continue;
- int id = oid.getAsInt();
- MapState mapState = FilledMapItem.getMapState(id, mc.world);
+ int id = idc.id();
+ MapState mapState = FilledMapItem.getMapState(idc, mc.world);
if (mapState == null)
continue;
- String name = ife.getHeldItemStack().hasCustomName() ? ife.getHeldItemStack().getName().getString() : "";
+ String name = ife.getHeldItemStack().contains(DataComponentTypes.CUSTOM_NAME) ? ife.getHeldItemStack().getName().getString() : "";
byte[] u8name = name.getBytes(StandardCharsets.UTF_8);
int bsz = 4 + 4 + u8name.length + 16384;
ByteBuffer buf = ByteBuffer.allocate(bsz);
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/MapTallyCommand.java b/src/main/java/org/chrisoft/trashyaddon/commands/MapTallyCommand.java
index cce0687..cfeaee8 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/MapTallyCommand.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/MapTallyCommand.java
@@ -8,6 +8,8 @@ import meteordevelopment.orbit.EventPriority;
import meteordevelopment.orbit.listeners.IListener;
import meteordevelopment.meteorclient.events.packets.InventoryEvent;
import net.minecraft.command.CommandSource;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.component.type.MapIdComponent;
import net.minecraft.client.MinecraftClient;
import net.minecraft.item.FilledMapItem;
import net.minecraft.item.ItemStack;
@@ -79,7 +81,10 @@ public class MapTallyCommand extends Command {
int nmaps = 0;
for (ItemStack s : stacks.subList(0, stacks.size() - 36)) {
if (s.getItem() instanceof FilledMapItem) {
- ids.add(FilledMapItem.getMapId(s));
+ MapIdComponent idc = s.getComponents().get(DataComponentTypes.MAP_ID);
+ if (idc == null)
+ continue;
+ ids.add(idc.id());
++nmaps;
}
}
diff --git a/src/main/java/org/chrisoft/trashyaddon/commands/argument/CEntityArgumentType.java b/src/main/java/org/chrisoft/trashyaddon/commands/argument/CEntityArgumentType.java
index c13c08c..e9206f4 100644
--- a/src/main/java/org/chrisoft/trashyaddon/commands/argument/CEntityArgumentType.java
+++ b/src/main/java/org/chrisoft/trashyaddon/commands/argument/CEntityArgumentType.java
@@ -65,7 +65,7 @@ public class CEntityArgumentType implements ArgumentType<CEntitySelector> {
public CEntitySelector parse(StringReader stringReader) throws CommandSyntaxException {
int i = 0;
- CEntitySelectorReader lv = new CEntitySelectorReader(stringReader);
+ CEntitySelectorReader lv = new CEntitySelectorReader(stringReader, true);
CEntitySelector lv2 = lv.read();
if (lv2.getLimit() > 1 && this.singleTarget) {
if (this.playersOnly) {
diff --git a/src/main/java/org/chrisoft/trashyaddon/modules/AcceptablePrices.java b/src/main/java/org/chrisoft/trashyaddon/modules/AcceptablePrices.java
index 4809640..624a47f 100644
--- a/src/main/java/org/chrisoft/trashyaddon/modules/AcceptablePrices.java
+++ b/src/main/java/org/chrisoft/trashyaddon/modules/AcceptablePrices.java
@@ -76,7 +76,7 @@ public class AcceptablePrices implements ICopyable<AcceptablePrices>, ISerializa
for (int i = 0; i < l.size(); ++i) {
NbtCompound a = l.getCompound(i);
String item_id = a.getString("Item");
- Item item = Registries.ITEM.get(new Identifier(item_id));
+ Item item = Registries.ITEM.get(Identifier.of(item_id));
int price = a.getInt("Price");
ret.put(item, price);
}
diff --git a/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java b/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java
index dfb343d..a062b38 100644
--- a/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java
+++ b/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java
@@ -39,7 +39,7 @@ public class AutoTrade extends Module {
Items.ROTTEN_FLESH,
Items.GOLD_INGOT,
Items.RABBIT_FOOT,
- Items.SCUTE,
+ Items.TURTLE_SCUTE,
Items.GLASS_BOTTLE,
Items.NETHER_WART,
Items.WHEAT,
@@ -184,11 +184,11 @@ public class AutoTrade extends Module {
private boolean isOfferEligible(TradeOffer o) {
// I don't give a SHIT to trades that use the second slot
// well actually I do, but I don't need THAT many enchanted books...
- if (!o.getSecondBuyItem().getItem().equals(Items.AIR))
+ if (o.getSecondBuyItem().isPresent() && !o.getSecondBuyItem().get().equals(Items.AIR))
return false;
if (o.isDisabled())
return false;
- ItemStack mbuy = o.getAdjustedFirstBuyItem();
+ ItemStack mbuy = o.getDisplayedFirstBuyItem();
ItemStack msell = o.getSellItem();
List<Item> sells = sellingEnabled.get() ? this.sellsSetting.get() : List.of();
List<Item> buys = buyingEnabled.get() ? this.buysSetting.get() : List.of();
@@ -223,7 +223,7 @@ public class AutoTrade extends Module {
ticksRemaining = -0xdead;
TradeOffer o = offers.get(currentOffer);
Item tradedItem = o.getSellItem().getItem().equals(Items.EMERALD) ?
- o.getAdjustedFirstBuyItem().getItem() : o.getSellItem().getItem();
+ o.getDisplayedFirstBuyItem().getItem() : o.getSellItem().getItem();
countBefore = screen.getScreenHandler().slots.stream()
.map(slot -> slot.getStack())
.filter(s -> s.getItem().equals(tradedItem))
@@ -236,7 +236,7 @@ public class AutoTrade extends Module {
private void finalizeCurrentTrade() {
TradeOffer o = offers.get(currentOffer);
Item tradedItem = o.getSellItem().getItem().equals(Items.EMERALD) ?
- o.getAdjustedFirstBuyItem().getItem() : o.getSellItem().getItem();
+ o.getDisplayedFirstBuyItem().getItem() : o.getSellItem().getItem();
countAfter = screen.getScreenHandler().slots.stream()
.map(slot -> slot.getStack())
.filter(s -> s.getItem().equals(tradedItem))
@@ -265,6 +265,7 @@ public class AutoTrade extends Module {
first = false;
}
info(f.toString());
+ f.close();
}
if (!itemsBought.isEmpty()) {
Formatter f = new Formatter();
@@ -275,6 +276,7 @@ public class AutoTrade extends Module {
first = false;
}
info(f.toString());
+ f.close();
}
}
if (autoClose.get() && (!itemsBought.isEmpty() || !itemsSold.isEmpty()))
@@ -293,7 +295,7 @@ public class AutoTrade extends Module {
return;
}
if (waitState != WaitState.None && currentOffer < offers.size() && (offers.get(currentOffer).isDisabled() ||
- screen.getScreenHandler().slots.get(0).getStack().getCount() < offers.get(currentOffer).getAdjustedFirstBuyItem().getCount())) {
+ screen.getScreenHandler().slots.get(0).getStack().getCount() < offers.get(currentOffer).getDisplayedFirstBuyItem().getCount())) {
// the WaitingForInventoryUpdate state is mostly useless because ScreenHandlerSlotUpdateS2CPacket
// isn't sent after the shift-click...
finalizeCurrentTrade();
diff --git a/src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java b/src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java
index 41910c7..2d5be7e 100644
--- a/src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java
+++ b/src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java
@@ -48,8 +48,8 @@ public class MatchedItemHighlight extends Module {
for (int j = firstInventorySlot; j < screenHandler.slots.size(); ++ j) {
if (screenHandler.getSlot(j).getStack().isEmpty())
continue;
- if (ItemStack.canCombine(screenHandler.getSlot(i).getStack(), screenHandler.getSlot(j).getStack()) ||
- ItemStack.canCombine(screenHandler.getSlot(j).getStack(), screenHandler.getSlot(i).getStack())) {
+ if (ItemStack.areItemsAndComponentsEqual(screenHandler.getSlot(i).getStack(), screenHandler.getSlot(j).getStack()) ||
+ ItemStack.areItemsAndComponentsEqual(screenHandler.getSlot(j).getStack(), screenHandler.getSlot(i).getStack())) {
Color c;
if (!slotColors.get(i).equals(transparent))
c = new Color(slotColors.get(i));