From 201a1510c8dbafdf1af7e2c7af51942b8323be03 Mon Sep 17 00:00:00 2001 From: Rektroth Date: Wed, 28 Aug 2024 21:41:01 -0400 Subject: [PATCH] Far from done. --- .../mixin/mc235045/CommandManagerMixin.java | 8 +- .../mc235045/EntitySelectorOptionsMixin.java | 118 ++++++++++++++++++ .../mc235045/EntitySelectorReaderMixin.java | 17 +++ src/main/resources/whiteout.mixins.json | 2 + 4 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorOptionsMixin.java create mode 100644 src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorReaderMixin.java diff --git a/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/CommandManagerMixin.java b/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/CommandManagerMixin.java index 8304a58..74bd455 100644 --- a/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/CommandManagerMixin.java +++ b/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/CommandManagerMixin.java @@ -78,8 +78,12 @@ private void changeSuggestions( if (requiredArgumentBuilder.getSuggestionsProvider() != null) { requiredArgumentBuilder.suggests(SuggestionProviders.getLocalProvider(requiredArgumentBuilder.getSuggestionsProvider())); - registeredAskServerSuggestionsForTree = requiredArgumentBuilder.getSuggestionsProvider() == SuggestionProviders.ASK_SERVER; - } else if (!registeredAskServerSuggestionsForTree && requiredArgumentBuilder.getType() instanceof EntityArgumentType) { + registeredAskServerSuggestionsForTree = + requiredArgumentBuilder.getSuggestionsProvider() == SuggestionProviders.ASK_SERVER; + } else if ( + !registeredAskServerSuggestionsForTree && + requiredArgumentBuilder.getType() instanceof EntityArgumentType + ) { requiredArgumentBuilder.suggests(requiredArgumentBuilder.getType()::listSuggestions); registeredAskServerSuggestionsForTree = true; } diff --git a/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorOptionsMixin.java b/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorOptionsMixin.java new file mode 100644 index 0000000..1fdd384 --- /dev/null +++ b/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorOptionsMixin.java @@ -0,0 +1,118 @@ +/* + * Patch for MC-235045 + * + * Authored for CraftBukkit/Spigot by Jake Potrebic on May 13, 2020. + * Ported to Fabric by Rektroth on August 25, 2024. + */ + +package io.github.rektroth.whiteout.mixin.mc235045; + +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import net.minecraft.command.CommandSource; +import net.minecraft.command.EntitySelectorOptions; + +import net.minecraft.command.EntitySelectorReader; +import net.minecraft.entity.EntityType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.Objects; +import java.util.function.Predicate; + +@Mixin(EntitySelectorOptions.class) +public abstract class EntitySelectorOptionsMixin { + @Unique + private static final DynamicCommandExceptionType ERROR_ENTITY_TAG_INVALID = new DynamicCommandExceptionType((object) -> { + return Text.of("Invalid or unknown entity type tag '" + object + "'"); + // missing hover text "You can disable this error in 'whiteout.properties'" + }); + + @Shadow + private static void putOption( + String id, + EntitySelectorOptions.SelectorHandler handler, + Predicate condition, + Text description + ) { } + + @Redirect( + at = @At( + ordinal = 15, + target = "Lnet/minecraft/command/EntitySelectorOptions;putOption(Ljava/lang/String;Lnet/minecraft/command/EntitySelectorOptions$SelectorHandler;Ljava/util/function/Predicate;Lnet/minecraft/text/Text;)V", + value = "INVOKE" + ), + method = "register" + ) + private static void fixedPutOption( + String id, + EntitySelectorOptions.SelectorHandler handler, + Predicate condition, + Text 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 EntitySelectorOptions.INAPPLICABLE_OPTION_EXCEPTION + .createWithContext(reader.getReader(), "type"); + } else { + if (bl) { + reader.setExcludesEntityType(); + } + + if (reader.readTagCharacter()) { + TagKey> tagKey = TagKey.of( + RegistryKeys.ENTITY_TYPE, + Identifier.fromCommandInput(reader.getReader())); + + if (/*reader.parsingEntityArgumentSuggestions &&*/ Registries.ENTITY_TYPE.getEntryList(tagKey).isEmpty()) { + reader.getReader().setCursor(i); + throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey); + } + + reader.addPredicate((entity) -> entity.getType().isIn(tagKey) != bl); + } else { + Identifier identifier = Identifier.fromCommandInput(reader.getReader()); + EntityType entityType = Registries.ENTITY_TYPE.getOrEmpty(identifier).orElseThrow(() -> { + reader.getReader().setCursor(i); + return EntitySelectorOptions.INVALID_TYPE_EXCEPTION + .createWithContext(reader.getReader(), identifier.toString()); + }); + + if (Objects.equals(EntityType.PLAYER, entityType) && !bl) { + reader.setIncludesNonPlayers(false); + } + + reader.addPredicate((entity) -> Objects.equals(entityType, entity.getType()) != bl); + + if (!bl) { + reader.setEntityType(entityType); + } + } + + } + }, (reader) -> !reader.selectsEntityType(), Text.translatable("argument.entity.options.type.description")); + } +} diff --git a/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorReaderMixin.java b/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorReaderMixin.java new file mode 100644 index 0000000..04fec52 --- /dev/null +++ b/src/main/java/io/github/rektroth/whiteout/mixin/mc235045/EntitySelectorReaderMixin.java @@ -0,0 +1,17 @@ +/* + * Patch for MC-235045 + * + * Authored for CraftBukkit/Spigot by Jake Potrebic on May 13, 2020. + * Ported to Fabric by Rektroth on August 25, 2024. + */ + +package io.github.rektroth.whiteout.mixin.mc235045; + +import net.minecraft.command.EntitySelectorReader; + +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(EntitySelectorReader.class) +public abstract class EntitySelectorReaderMixin { + // nothing yet +} diff --git a/src/main/resources/whiteout.mixins.json b/src/main/resources/whiteout.mixins.json index 738045b..94b63a8 100644 --- a/src/main/resources/whiteout.mixins.json +++ b/src/main/resources/whiteout.mixins.json @@ -30,6 +30,8 @@ "mc224454.AzaleaBlockMixin", "mc235045.CommandManagerMixin", "mc235045.EntityArgumentTypeMixin", + "mc235045.EntitySelectorOptionsMixin", + "mc235045.EntitySelectorReaderMixin", "mc235045.ServerCommandSourceMixin", "mc248588.LeveledCauldronBlockMixin", "mc253721.DeOpCommandMixin",