From 39524c4a8056f41ff0c2405d5e68446d5ca3cdad Mon Sep 17 00:00:00 2001 From: TreeOne <53233736+tr330ne@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:22:31 +0100 Subject: [PATCH 1/7] Add blacklist field to Config class --- src/main/java/com/zenith/util/config/Config.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/zenith/util/config/Config.java b/src/main/java/com/zenith/util/config/Config.java index 92c0f3f93..4ef9b1f8d 100644 --- a/src/main/java/com/zenith/util/config/Config.java +++ b/src/main/java/com/zenith/util/config/Config.java @@ -433,6 +433,7 @@ public static final class AutoEat { public boolean warning = true; public boolean warningMention = false; public boolean allowUnsafeFood = false; + public List blacklist = new ArrayList<>(); } public static final class AutoOmen { From 2d66e74864aee51b8e8ae8cbe66610a62aadf8f6 Mon Sep 17 00:00:00 2001 From: TreeOne <53233736+tr330ne@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:24:16 +0100 Subject: [PATCH 2/7] Enhance hasFood method to include blacklist check --- src/main/java/com/zenith/module/impl/AutoEat.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/zenith/module/impl/AutoEat.java b/src/main/java/com/zenith/module/impl/AutoEat.java index bd886df67..a890748c0 100644 --- a/src/main/java/com/zenith/module/impl/AutoEat.java +++ b/src/main/java/com/zenith/module/impl/AutoEat.java @@ -162,6 +162,7 @@ boolean hasFood(boolean ignoreHunger, ItemStack itemStack) { FoodData foodData = FoodRegistry.REGISTRY.get(itemStack.getId()); boolean canEat = ignoreHunger || CACHE.getPlayerCache().getThePlayer().getFood() < 20; return foodData != null + && !CONFIG.client.extra.autoEat.blacklist.contains(foodData.name()) && (CONFIG.client.extra.autoEat.allowUnsafeFood || foodData.isSafeFood()) && (canEat || foodData.canAlwaysEat()); } From 21579079599f2f4f3df25b9af5e029ec1eccee63 Mon Sep 17 00:00:00 2001 From: TreeOne <53233736+tr330ne@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:25:36 +0100 Subject: [PATCH 3/7] Add blacklist commands to AutoEatCommand --- src/main/java/com/zenith/command/impl/AutoEatCommand.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/zenith/command/impl/AutoEatCommand.java b/src/main/java/com/zenith/command/impl/AutoEatCommand.java index b3b859bd3..f97aa86e3 100644 --- a/src/main/java/com/zenith/command/impl/AutoEatCommand.java +++ b/src/main/java/com/zenith/command/impl/AutoEatCommand.java @@ -29,7 +29,11 @@ public CommandUsage commandUsage() { "health ", "hunger ", "warning on/off", - "allowUnsafeFood on/off" + "allowUnsafeFood on/off", + "blacklist add ", + "blacklist remove ", + "blacklist list", + "blacklist clear" ) .build(); } From b3ebe2b23f90210c598a43fb3f97ec0d4ee3e75d Mon Sep 17 00:00:00 2001 From: TreeOne <53233736+tr330ne@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:31:27 +0100 Subject: [PATCH 4/7] Add blacklist management for AutoEat command --- .../zenith/command/impl/AutoEatCommand.java | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/zenith/command/impl/AutoEatCommand.java b/src/main/java/com/zenith/command/impl/AutoEatCommand.java index f97aa86e3..a0e27fa4b 100644 --- a/src/main/java/com/zenith/command/impl/AutoEatCommand.java +++ b/src/main/java/com/zenith/command/impl/AutoEatCommand.java @@ -1,12 +1,14 @@ package com.zenith.command.impl; import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.zenith.command.api.Command; import com.zenith.command.api.CommandCategory; import com.zenith.command.api.CommandContext; import com.zenith.command.api.CommandUsage; import com.zenith.discord.Embed; +import com.zenith.mc.food.FoodRegistry; import com.zenith.module.impl.AutoEat; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; @@ -70,7 +72,43 @@ public LiteralArgumentBuilder register() { CONFIG.client.extra.autoEat.allowUnsafeFood = getToggle(c, "toggle"); c.getSource().getEmbed() .title("AutoEat Allow Unsafe Food " + toggleStrCaps(CONFIG.client.extra.autoEat.allowUnsafeFood)); - }))); + }))) + .then(literal("blacklist") + .then(literal("add").then(argument("food", StringArgumentType.word()).executes(c -> { + String food = StringArgumentType.getString(c, "food"); + if (FoodRegistry.REGISTRY.get(food) == null) { + c.getSource().getEmbed() + .title("AutoEat Blacklist: Unknown food \"" + food + "\"") + .errorColor(); + return OK; + } + if (!CONFIG.client.extra.autoEat.blacklist.contains(food)) + CONFIG.client.extra.autoEat.blacklist.add(food); + c.getSource().getEmbed() + .title("AutoEat Blacklist: Added \"" + food + "\""); + return OK; + }))) + .then(literal("remove").then(argument("food", StringArgumentType.word()).executes(c -> { + String food = StringArgumentType.getString(c, "food"); + CONFIG.client.extra.autoEat.blacklist.remove(food); + c.getSource().getEmbed() + .title("AutoEat Blacklist: Removed \"" + food + "\""); + return OK; + }))) + .then(literal("list").executes(c -> { + c.getSource().getEmbed() + .title("AutoEat Blacklist") + .addField("Foods", CONFIG.client.extra.autoEat.blacklist.isEmpty() + ? "Empty" + : String.join(", ", CONFIG.client.extra.autoEat.blacklist)); + return OK; + })) + .then(literal("clear").executes(c -> { + CONFIG.client.extra.autoEat.blacklist.clear(); + c.getSource().getEmbed().title("AutoEat Blacklist Cleared"); + return OK; + })) + ); } @Override From 627464c3557ff8fe8f894bce8d8c332302f53525 Mon Sep 17 00:00:00 2001 From: TreeOne <53233736+tr330ne@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:34:00 +0100 Subject: [PATCH 5/7] Add blacklist field to AutoEatCommand --- src/main/java/com/zenith/command/impl/AutoEatCommand.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/zenith/command/impl/AutoEatCommand.java b/src/main/java/com/zenith/command/impl/AutoEatCommand.java index a0e27fa4b..edce45fab 100644 --- a/src/main/java/com/zenith/command/impl/AutoEatCommand.java +++ b/src/main/java/com/zenith/command/impl/AutoEatCommand.java @@ -119,6 +119,9 @@ public void defaultEmbed(final Embed builder) { .addField("Hunger Threshold", CONFIG.client.extra.autoEat.hungerThreshold) .addField("Warning", toggleStr(CONFIG.client.extra.autoEat.warning)) .addField("Allow Unsafe Food", toggleStr(CONFIG.client.extra.autoEat.allowUnsafeFood)) + .addField("Blacklist", CONFIG.client.extra.autoEat.blacklist.isEmpty() + ? "Empty" + : String.join(", ", CONFIG.client.extra.autoEat.blacklist)) .primaryColor(); } } From 09e9f5fcc857cf4e1341f62be62565f6999749a4 Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Fri, 20 Feb 2026 17:36:59 -0800 Subject: [PATCH 6/7] configurable mode + food cmd arg type + update docs --- docs/wiki/Commands.md | 22 +++ .../command/brigadier/FoodArgument.java | 80 +++++++++++ .../zenith/command/impl/AutoEatCommand.java | 130 ++++++++++++------ .../java/com/zenith/module/impl/AutoEat.java | 18 ++- .../java/com/zenith/util/config/Config.java | 8 +- 5 files changed, 210 insertions(+), 48 deletions(-) create mode 100644 src/main/java/com/zenith/command/brigadier/FoodArgument.java diff --git a/docs/wiki/Commands.md b/docs/wiki/Commands.md index 1fc424883..a8f1e7f7c 100644 --- a/docs/wiki/Commands.md +++ b/docs/wiki/Commands.md @@ -1468,6 +1468,18 @@ Dropping can be configured based on modes: Automatically eats food when health or hunger is below a set threshold. + + +Which foods to eat can be configured based on modes: + + + + * `all`: any food + + * `whitelist`: only added foods + + * `blacklist`: any food not added + **Usage** ```autoEat on/off``` @@ -1480,6 +1492,16 @@ Automatically eats food when health or hunger is below a set threshold. ```autoEat allowUnsafeFood on/off``` + ```autoEat mode ``` + + ```autoEat add/del ``` + + ```autoEat addAll ,,...``` + + ```autoEat list``` + + ```autoEat clear``` + ### autoFish diff --git a/src/main/java/com/zenith/command/brigadier/FoodArgument.java b/src/main/java/com/zenith/command/brigadier/FoodArgument.java new file mode 100644 index 000000000..70995a2bc --- /dev/null +++ b/src/main/java/com/zenith/command/brigadier/FoodArgument.java @@ -0,0 +1,80 @@ +package com.zenith.command.brigadier; + +import com.mojang.brigadier.LiteralMessage; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import com.zenith.mc.food.FoodData; +import com.zenith.mc.food.FoodRegistry; +import lombok.Data; +import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser; +import org.jspecify.annotations.NonNull; + +import java.util.concurrent.CompletableFuture; + +@Data +public class FoodArgument implements SerializableArgumentType { + public static final SimpleCommandExceptionType INVALID_ITEM_EXCEPTION = new SimpleCommandExceptionType( + new LiteralMessage("Invalid item") + ); + + public static FoodArgument food() { + return new FoodArgument(); + } + + @Override + public FoodData parse(final StringReader reader) throws CommandSyntaxException { + int i = reader.getCursor(); + var itemName = readItemString(reader); + if (itemName.contains(":")) { + // may look like minecraft:item_name + var itemNameNamespaceSplit = itemName.split(":"); + if (itemNameNamespaceSplit.length != 2) { + reader.setCursor(i); + throw INVALID_ITEM_EXCEPTION.create(); + } + itemName = itemNameNamespaceSplit[1]; + } + var itemData = FoodRegistry.REGISTRY.get(itemName); + if (itemData == null) { + reader.setCursor(i); + throw INVALID_ITEM_EXCEPTION.create(); + } + return itemData; + } + + public static FoodData getFood(final CommandContext context, String name) { + return context.getArgument(name, FoodData.class); + } + + private String readItemString(StringReader reader) throws CommandSyntaxException { + final int start = reader.getCursor(); + while (reader.canRead() && isAllowedInItemString(reader.peek())) { + reader.skip(); + } + if (reader.getCursor() == start) { + reader.setCursor(start); + throw INVALID_ITEM_EXCEPTION.createWithContext(reader); + } + return reader.getString().substring(start, reader.getCursor()); + } + + private static boolean isAllowedInItemString(final char c) { + return c >= 'A' && c <= 'Z' + || c >= 'a' && c <= 'z' + || c == '_' || c == ':'; + } + + @Override + public @NonNull CommandParser commandParser() { + return CommandParser.ITEM_STACK; + } + + @Override + public CompletableFuture listSuggestions(final CommandContext context, final SuggestionsBuilder builder) { + return RegistryDataArgument.listRegistrySuggestions(context, builder, FoodRegistry.REGISTRY); + } +} diff --git a/src/main/java/com/zenith/command/impl/AutoEatCommand.java b/src/main/java/com/zenith/command/impl/AutoEatCommand.java index edce45fab..0ebfd455a 100644 --- a/src/main/java/com/zenith/command/impl/AutoEatCommand.java +++ b/src/main/java/com/zenith/command/impl/AutoEatCommand.java @@ -7,13 +7,21 @@ import com.zenith.command.api.CommandCategory; import com.zenith.command.api.CommandContext; import com.zenith.command.api.CommandUsage; -import com.zenith.discord.Embed; import com.zenith.mc.food.FoodRegistry; import com.zenith.module.impl.AutoEat; +import com.zenith.util.config.Config; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; import static com.zenith.Globals.CONFIG; import static com.zenith.Globals.MODULE; +import static com.zenith.command.brigadier.CustomStringArgumentType.getString; +import static com.zenith.command.brigadier.FoodArgument.food; +import static com.zenith.command.brigadier.FoodArgument.getFood; +import static com.zenith.command.brigadier.ItemArgument.item; import static com.zenith.command.brigadier.ToggleArgumentType.getToggle; import static com.zenith.command.brigadier.ToggleArgumentType.toggle; @@ -25,6 +33,12 @@ public CommandUsage commandUsage() { .category(CommandCategory.MODULE) .description(""" Automatically eats food when health or hunger is below a set threshold. + + Which foods to eat can be configured based on modes: + + * `all`: any food + * `whitelist`: only added foods + * `blacklist`: any food not added """) .usageLines( "on/off", @@ -32,10 +46,11 @@ public CommandUsage commandUsage() { "hunger ", "warning on/off", "allowUnsafeFood on/off", - "blacklist add ", - "blacklist remove ", - "blacklist list", - "blacklist clear" + "mode ", + "add/del ", + "addAll ,,...", + "list", + "clear" ) .build(); } @@ -73,55 +88,82 @@ public LiteralArgumentBuilder register() { c.getSource().getEmbed() .title("AutoEat Allow Unsafe Food " + toggleStrCaps(CONFIG.client.extra.autoEat.allowUnsafeFood)); }))) - .then(literal("blacklist") - .then(literal("add").then(argument("food", StringArgumentType.word()).executes(c -> { - String food = StringArgumentType.getString(c, "food"); - if (FoodRegistry.REGISTRY.get(food) == null) { - c.getSource().getEmbed() - .title("AutoEat Blacklist: Unknown food \"" + food + "\"") - .errorColor(); - return OK; + .then(literal("mode").then(argument("mode", enumStrings("all", "whitelist", "blacklist")).executes(c -> { + var modeString = getString(c, "mode").toUpperCase(); + CONFIG.client.extra.autoEat.mode = Config.Client.Extra.AutoEat.Mode.valueOf(modeString); + c.getSource().getEmbed() + .title("Mode Set"); + }))) + .then(literal("add").then(argument("food", food()).executes(c -> { + var food = getFood(c, "food"); + CONFIG.client.extra.autoEat.foods.add(food.name()); + CONFIG.client.extra.autoEat.foods.removeIf(i -> FoodRegistry.REGISTRY.get(i) == null); + c.getSource().getEmbed() + .title("Food Added") + .description(foodList()); + }))) + .then(literal("addAll").then(argument("foods", StringArgumentType.greedyString()).executes(c -> { + var foodList = getString(c, "foods").split(","); + List invalidFoods = new ArrayList<>(); + for (var food : foodList) { + var foodData = FoodRegistry.REGISTRY.get(food); + if (foodData == null) { + invalidFoods.add(food); + continue; } - if (!CONFIG.client.extra.autoEat.blacklist.contains(food)) - CONFIG.client.extra.autoEat.blacklist.add(food); - c.getSource().getEmbed() - .title("AutoEat Blacklist: Added \"" + food + "\""); - return OK; - }))) - .then(literal("remove").then(argument("food", StringArgumentType.word()).executes(c -> { - String food = StringArgumentType.getString(c, "food"); - CONFIG.client.extra.autoEat.blacklist.remove(food); - c.getSource().getEmbed() - .title("AutoEat Blacklist: Removed \"" + food + "\""); - return OK; - }))) - .then(literal("list").executes(c -> { + CONFIG.client.extra.autoEat.foods.add(foodData.name()); + } + c.getSource().getEmbed() + .title("Foods Added") + .addField("Added Foods Count", foodList.length - invalidFoods.size()) + .description(foodList()); + if (!invalidFoods.isEmpty()) { c.getSource().getEmbed() - .title("AutoEat Blacklist") - .addField("Foods", CONFIG.client.extra.autoEat.blacklist.isEmpty() - ? "Empty" - : String.join(", ", CONFIG.client.extra.autoEat.blacklist)); - return OK; - })) - .then(literal("clear").executes(c -> { - CONFIG.client.extra.autoEat.blacklist.clear(); - c.getSource().getEmbed().title("AutoEat Blacklist Cleared"); - return OK; - })) - ); + .addField("Invalid Foods", invalidFoods.stream().map(s -> "`" + s + "`").reduce((a, b) -> a + ", " + b).orElse("")); + } + }))) + .then(literal("del").then(argument("food", item()).executes(c -> { + var food = getFood(c, "food"); + CONFIG.client.extra.autoEat.foods.remove(food.name()); + CONFIG.client.extra.autoEat.foods.removeIf(i -> FoodRegistry.REGISTRY.get(i) == null); + c.getSource().getEmbed() + .title("Food Deleted") + .description(foodList()); + }))) + .then(literal("list").executes(c -> { + CONFIG.client.extra.autoEat.foods.removeIf(i -> FoodRegistry.REGISTRY.get(i) == null); + c.getSource().getEmbed() + .title("Food Blacklist") + .description(foodList()); + })) + .then(literal("clear").executes(c -> { + CONFIG.client.extra.autoEat.foods.clear(); + c.getSource().getEmbed() + .title("Food Blacklist Cleared") + .description(foodList()); + })); } @Override - public void defaultEmbed(final Embed builder) { - builder + public void defaultHandler(final CommandContext context) { + if (context.getData().containsKey("noDefaultEmbed")) return; + context.getEmbed() .addField("AutoEat", toggleStr(CONFIG.client.extra.autoEat.enabled)) + .addField("Mode", CONFIG.client.extra.autoEat.mode.name().toLowerCase()) .addField("Health Threshold", CONFIG.client.extra.autoEat.healthThreshold) .addField("Hunger Threshold", CONFIG.client.extra.autoEat.hungerThreshold) .addField("Warning", toggleStr(CONFIG.client.extra.autoEat.warning)) .addField("Allow Unsafe Food", toggleStr(CONFIG.client.extra.autoEat.allowUnsafeFood)) - .addField("Blacklist", CONFIG.client.extra.autoEat.blacklist.isEmpty() - ? "Empty" - : String.join(", ", CONFIG.client.extra.autoEat.blacklist)) .primaryColor(); } + + String foodList() { + var items = new ArrayList<>(CONFIG.client.extra.autoEat.foods); + Collections.sort(items); + String list = "**Food List**:\n" + String.join("\n", items); + if (list.length() > 4000) { + list = list.substring(0, 4000) + "\n... (and more)"; + } + return list; + } } diff --git a/src/main/java/com/zenith/module/impl/AutoEat.java b/src/main/java/com/zenith/module/impl/AutoEat.java index a890748c0..ade3bc30c 100644 --- a/src/main/java/com/zenith/module/impl/AutoEat.java +++ b/src/main/java/com/zenith/module/impl/AutoEat.java @@ -160,10 +160,22 @@ public boolean itemPredicate(final ItemStack itemStack) { boolean hasFood(boolean ignoreHunger, ItemStack itemStack) { FoodData foodData = FoodRegistry.REGISTRY.get(itemStack.getId()); + if (foodData == null) return false; + switch (CONFIG.client.extra.autoEat.mode) { + case BLACKLIST -> { + if (CONFIG.client.extra.autoEat.foods.contains(foodData.name())) { + return false; + } + } + case WHITELIST -> { + if (!CONFIG.client.extra.autoEat.foods.contains(foodData.name())) { + return false; + } + } + case ALL -> {} + } boolean canEat = ignoreHunger || CACHE.getPlayerCache().getThePlayer().getFood() < 20; - return foodData != null - && !CONFIG.client.extra.autoEat.blacklist.contains(foodData.name()) - && (CONFIG.client.extra.autoEat.allowUnsafeFood || foodData.isSafeFood()) + return (CONFIG.client.extra.autoEat.allowUnsafeFood || foodData.isSafeFood()) && (canEat || foodData.canAlwaysEat()); } diff --git a/src/main/java/com/zenith/util/config/Config.java b/src/main/java/com/zenith/util/config/Config.java index 4ef9b1f8d..4634ab18a 100644 --- a/src/main/java/com/zenith/util/config/Config.java +++ b/src/main/java/com/zenith/util/config/Config.java @@ -433,7 +433,13 @@ public static final class AutoEat { public boolean warning = true; public boolean warningMention = false; public boolean allowUnsafeFood = false; - public List blacklist = new ArrayList<>(); + public Mode mode = Mode.ALL; + public enum Mode { + ALL, + BLACKLIST, + WHITELIST + } + public HashSet foods = new HashSet<>(); } public static final class AutoOmen { From 7631b58551e318843a5f381729eb12f1041ec19a Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Sat, 21 Feb 2026 20:12:20 -0800 Subject: [PATCH 7/7] update graalvm reachability metadata --- .../native-image/reachability-metadata.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/resources/META-INF/native-image/reachability-metadata.json b/src/main/resources/META-INF/native-image/reachability-metadata.json index 7cbb14e74..256716885 100644 --- a/src/main/resources/META-INF/native-image/reachability-metadata.json +++ b/src/main/resources/META-INF/native-image/reachability-metadata.json @@ -2678,6 +2678,20 @@ } ] }, + { + "type": "com.zenith.util.config.Config$Client$Extra$AutoEat$Mode", + "fields": [ + { + "name": "ALL" + }, + { + "name": "BLACKLIST" + }, + { + "name": "WHITELIST" + } + ] + }, { "type": "com.zenith.util.config.Config$Client$Extra$AutoFish", "allDeclaredFields": true, @@ -8776,4 +8790,4 @@ } ] } -} +} \ No newline at end of file