From fd53a7b3cb8dd445c64ba017cf77b6dfe98594b9 Mon Sep 17 00:00:00 2001 From: Nougato Date: Wed, 16 Oct 2024 00:12:49 +0200 Subject: [PATCH] feat: add match & list command to test in game regex result + fix: now the hopper will not stop at the first mismatch, it will test all items inside a container --- .gitignore | 3 +- .../brn/regexinghoppers/RegexingHoppers.java | 65 ++-------------- .../commands/RegexHoppersCommands.java | 77 +++++++++++++++++++ .../mixin/RegexingHopperMixin.java | 40 ++++------ .../brn/regexinghoppers/util/Tools.java | 56 ++++++++++++++ 5 files changed, 157 insertions(+), 84 deletions(-) create mode 100644 src/main/java/systems/brn/regexinghoppers/commands/RegexHoppersCommands.java create mode 100644 src/main/java/systems/brn/regexinghoppers/util/Tools.java diff --git a/.gitignore b/.gitignore index 3c37caf..477a740 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,8 @@ *.iml *.ipr *.iws - +#VS Code things +.vscode/ # IntelliJ out/ # mpeltonen/sbt-idea plugin diff --git a/src/main/java/systems/brn/regexinghoppers/RegexingHoppers.java b/src/main/java/systems/brn/regexinghoppers/RegexingHoppers.java index 2c7af6e..f45841d 100644 --- a/src/main/java/systems/brn/regexinghoppers/RegexingHoppers.java +++ b/src/main/java/systems/brn/regexinghoppers/RegexingHoppers.java @@ -1,20 +1,13 @@ package systems.brn.regexinghoppers; + import net.fabricmc.api.ModInitializer; -import net.minecraft.block.entity.HopperBlockEntity; -import net.minecraft.inventory.Inventory; -import net.minecraft.screen.NamedScreenHandlerFactory; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import systems.brn.regexinghoppers.mixin.HopperBlockEntityAccessor; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; +import systems.brn.regexinghoppers.commands.RegexHoppersCommands; public class RegexingHoppers implements ModInitializer { - // This logger is used to write text to the console and the log file. - // It is considered best practice to use your mod id as the logger's name. - // That way, it's clear which mod wrote info, warnings, and errors. public static final Logger LOGGER = LoggerFactory.getLogger("RegexingHoppers"); @Override @@ -23,54 +16,8 @@ public class RegexingHoppers implements ModInitializer { // However, some things (like resources) may still be uninitialized. // Proceed with mild caution. LOGGER.debug("RegexingHoppers initialized!"); - } - - public static boolean shouldNotMove(Inventory hopper, String itemName) { - // Log entering the method with given parameters - LOGGER.debug("Entering shouldNotMove with itemName: {}", itemName); - - if (hopper instanceof NamedScreenHandlerFactory factory) { - String customName = factory.getDisplayName().getLiteralString(); - - // Log the custom name used for matching - LOGGER.debug("Custom regex pattern from hopper: {}", customName); - - if (customName != null && !customName.isEmpty()) { - if (hopper instanceof HopperBlockEntity) { - HopperBlockEntityAccessor hopperAccessor = (HopperBlockEntityAccessor) hopper; - if (hopperAccessor.getTransferCooldown() > 1) { - return true; - } - } - try { - Pattern pattern = Pattern.compile(customName); - Matcher matcher = pattern.matcher(itemName); - - // Log the result of the regex matching - boolean matches = matcher.matches(); - LOGGER.debug("Regex matching result: {}", matches); - - if (!matches) { - if (hopper instanceof HopperBlockEntity) { - HopperBlockEntityAccessor hopperAccessor = (HopperBlockEntityAccessor) hopper; - hopperAccessor.setTransferCooldown(8); - } - } - return !matches; - } catch (PatternSyntaxException e) { - // Log exception if regex pattern is invalid - LOGGER.debug("Invalid regex pattern: {}", customName, e); - } - } else { - // Log case when custom name is null or empty - LOGGER.debug("Custom name is null or empty, not performing regex matching."); - } - } else { - // Log if hopper is not an instance of NamedScreenHandlerFactory - LOGGER.debug("Hopper is not an instance of NamedScreenHandlerFactory."); - } - - // Default return value in case no conditions are met - return false; + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + RegexHoppersCommands.register(dispatcher); + }); } } \ No newline at end of file diff --git a/src/main/java/systems/brn/regexinghoppers/commands/RegexHoppersCommands.java b/src/main/java/systems/brn/regexinghoppers/commands/RegexHoppersCommands.java new file mode 100644 index 0000000..ffe3ab7 --- /dev/null +++ b/src/main/java/systems/brn/regexinghoppers/commands/RegexHoppersCommands.java @@ -0,0 +1,77 @@ +package systems.brn.regexinghoppers.commands; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import systems.brn.regexinghoppers.util.Tools; +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import java.util.regex.PatternSyntaxException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static net.minecraft.server.command.CommandManager.argument; +import static net.minecraft.server.command.CommandManager.literal; + +public class RegexHoppersCommands { + public static final Logger LOGGER = LoggerFactory.getLogger("RegexingHoppers"); + + // TODO: Add config file for permissions system + public static void register(CommandDispatcher dispatcher) { + dispatcher.register(literal("regexhoppers") + .then(literal("match") + .then(argument("regex", StringArgumentType.greedyString()) + .executes(context -> executeMatch(context.getSource(), StringArgumentType.getString(context, "regex"))))) + .then(literal("list") + .then(argument("regex", StringArgumentType.greedyString()) + .executes(context -> executeList(context.getSource(), StringArgumentType.getString(context, "regex")))))); + } + + private static int executeMatch(ServerCommandSource source, final String regexString) { + try { + int count = 0; + + for (Identifier id : Registries.ITEM.getIds()) { + Item item = Registries.ITEM.get(id); + String itemName = Tools.getNameOf(item); + if (Tools.itemMatch(itemName, regexString)) { + count++; + } + } + + final int total = count; + + source.sendFeedback(() -> Text.literal(regexString + " match with " + total + " items"), false); + return 1; + } catch (PatternSyntaxException e) { + return 0; + } + } + + private static int executeList(ServerCommandSource source, final String regexString) { + try { + int count = 0; + String allMatchs = ""; + + for (Identifier id : Registries.ITEM.getIds()) { + Item item = Registries.ITEM.get(id); + String itemName = item.getName().getString().toLowerCase(); + if (Tools.itemMatch(itemName, regexString)) { + count++; + allMatchs += itemName + "\n"; + } + } + + final int total = count; + final String totalAllMatchs = allMatchs; + + source.sendFeedback(() -> Text.literal("Full match list: \n" + totalAllMatchs + regexString + " match with " + total + " items: \n"), false); + return 1; + } catch (PatternSyntaxException e) { + return 0; + } + } +} \ No newline at end of file diff --git a/src/main/java/systems/brn/regexinghoppers/mixin/RegexingHopperMixin.java b/src/main/java/systems/brn/regexinghoppers/mixin/RegexingHopperMixin.java index 4f95e9a..57c7901 100644 --- a/src/main/java/systems/brn/regexinghoppers/mixin/RegexingHopperMixin.java +++ b/src/main/java/systems/brn/regexinghoppers/mixin/RegexingHopperMixin.java @@ -3,40 +3,32 @@ package systems.brn.regexinghoppers.mixin; import net.minecraft.block.entity.HopperBlockEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; -import net.minecraft.registry.Registries; +import net.minecraft.screen.NamedScreenHandlerFactory; import net.minecraft.util.math.Direction; + import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import systems.brn.regexinghoppers.RegexingHoppers; +import systems.brn.regexinghoppers.util.Tools; @Mixin(HopperBlockEntity.class) public class RegexingHopperMixin { - @Inject(method = "transfer(Lnet/minecraft/inventory/Inventory;Lnet/minecraft/inventory/Inventory;Lnet/minecraft/item/ItemStack;ILnet/minecraft/util/math/Direction;)Lnet/minecraft/item/ItemStack;", - at = @At(value = "HEAD"), - cancellable = true - ) - private static void processContainer(Inventory from, Inventory _to, ItemStack stack, int slot, Direction side, CallbackInfoReturnable cir) { - final String itemName = Registries.ITEM.getId(stack.getItem()).toString(); - if(from != null) { - if (RegexingHoppers.shouldNotMove(from, itemName)) { - cir.setReturnValue(stack); - if(from instanceof HopperBlockEntity) { - ((HopperBlockEntityAccessor) from).setTransferCooldown(8); - } - return; - } + + @Inject(method = "canExtract", at = @At(value = "HEAD"), cancellable = true) + private static void canExtractReplacer(Inventory outputInventory, Inventory inputInventory, ItemStack stack, + int slot, Direction side, CallbackInfoReturnable cir) { + + if (outputInventory == null) { + return; } - if(_to != null) { - if (RegexingHoppers.shouldNotMove(_to, itemName)) { - cir.setReturnValue(stack); - if(_to instanceof HopperBlockEntity) { - ((HopperBlockEntityAccessor) _to).setTransferCooldown(8); - } - return; + + if (outputInventory instanceof NamedScreenHandlerFactory factory) { + String customName = factory.getDisplayName().getLiteralString(); + if (customName != null) { + Boolean canExtract = Tools.shouldMove(outputInventory, stack.getItem()); + cir.setReturnValue(canExtract); } } } } - diff --git a/src/main/java/systems/brn/regexinghoppers/util/Tools.java b/src/main/java/systems/brn/regexinghoppers/util/Tools.java new file mode 100644 index 0000000..2ccb349 --- /dev/null +++ b/src/main/java/systems/brn/regexinghoppers/util/Tools.java @@ -0,0 +1,56 @@ +package systems.brn.regexinghoppers.util; + +import java.util.regex.PatternSyntaxException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.block.entity.HopperBlockEntity; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.Item; +import net.minecraft.screen.NamedScreenHandlerFactory; +import systems.brn.regexinghoppers.mixin.HopperBlockEntityAccessor; + +public class Tools { + public static final Logger LOGGER = LoggerFactory.getLogger("RegexingHoppers"); + + public static boolean itemMatch(String itemName, String regex) { + return itemName.matches(regex); + } + + public static String getNameOf(Item item) { + return item.getName().getString().toLowerCase(); + } + + public static boolean shouldMove(Inventory hopper, Item item) { + if (!(hopper instanceof NamedScreenHandlerFactory)) { + // Log if hopper is not an instance of NamedScreenHandlerFactory + LOGGER.debug("Hopper is not an instance of NamedScreenHandlerFactory."); + return true; + } + NamedScreenHandlerFactory factory = (NamedScreenHandlerFactory) hopper; + String customName = factory.getDisplayName().getLiteralString(); + if (customName == null || customName.isEmpty()) { + // Log case when custom name is null or empty + LOGGER.debug("Custom name is null or empty, not performing regex matching."); + return true; + } + + // TODO: Test if this code still needed + if (hopper instanceof HopperBlockEntity) { + HopperBlockEntityAccessor hopperAccessor = (HopperBlockEntityAccessor) hopper; + if (hopperAccessor.getTransferCooldown() > 1) { + return false; + } + } + + try { + return Tools.itemMatch(getNameOf(item), customName); + } catch (PatternSyntaxException e) { + // Log exception if regex pattern is invalid + LOGGER.debug("Invalid regex pattern: {}", customName, e); + } + + return true; + } +}