From 7f4ba5fc0985668f0284b7a4de6d6f52f073a114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ko=C5=88a=C5=99=C3=ADk?= Date: Sun, 27 Nov 2022 14:11:40 +0100 Subject: [PATCH] Add configurable item ordering options --- .../java/cpw/mods/inventorysorter/Config.java | 7 ++ .../mods/inventorysorter/InventorySorter.java | 12 ++++ .../InventorySorterCommand.java | 11 +++- .../mods/inventorysorter/ItemOrdering.java | 65 +++++++++++++++++++ .../mods/inventorysorter/SortingHandler.java | 9 ++- .../assets/inventorysorter/lang/en_us.json | 3 +- .../assets/inventorysorter/lang/en_us.lang | 3 +- 7 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 src/main/java/cpw/mods/inventorysorter/ItemOrdering.java diff --git a/src/main/java/cpw/mods/inventorysorter/Config.java b/src/main/java/cpw/mods/inventorysorter/Config.java index f96e66a..870843a 100644 --- a/src/main/java/cpw/mods/inventorysorter/Config.java +++ b/src/main/java/cpw/mods/inventorysorter/Config.java @@ -19,6 +19,8 @@ public class Config { final ForgeConfigSpec.ConfigValue> containerBlacklist; final ForgeConfigSpec.ConfigValue> slotBlacklist; + final ForgeConfigSpec.ConfigValue itemOrdering; + private Config(ForgeConfigSpec.Builder builder) { builder.comment("Inventory sorter blacklists"); builder.push("blacklists"); @@ -31,5 +33,10 @@ private Config(ForgeConfigSpec.Builder builder) { .translation("inventorysorter.config.slotblacklist") .defineList("slotBlacklist", new ArrayList<>(), t -> true); builder.pop(); + + itemOrdering = builder + .comment("Item ordering method") + .translation("inventorysorter.config.itemordering") + .defineEnum("itemOrdering", ItemOrdering.BY_COUNT); } } diff --git a/src/main/java/cpw/mods/inventorysorter/InventorySorter.java b/src/main/java/cpw/mods/inventorysorter/InventorySorter.java index 16ea38c..7747154 100644 --- a/src/main/java/cpw/mods/inventorysorter/InventorySorter.java +++ b/src/main/java/cpw/mods/inventorysorter/InventorySorter.java @@ -66,6 +66,8 @@ public class InventorySorter final Set imcSlotBlacklist = new HashSet<>(); final Set imcContainerBlacklist = new HashSet<>(); + ItemOrdering itemOrdering = ItemOrdering.BY_COUNT; + public InventorySorter() { INSTANCE = this; final IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); @@ -140,11 +142,13 @@ private void updateBlacklists() { private void updateConfig() { Config.CONFIG.containerBlacklist.set(containerblacklist.stream().filter(e -> !imcContainerBlacklist.contains(e)).map(Objects::toString).collect(Collectors.toList())); Config.CONFIG.slotBlacklist.set(slotblacklist.stream().filter(e -> !imcSlotBlacklist.contains(e)).collect(Collectors.toList())); + Config.CONFIG.itemOrdering.set(itemOrdering); updateBlacklists(); } void onConfigLoad(ModConfigEvent configEvent) { + itemOrdering = Config.CONFIG.itemOrdering.get(); updateBlacklists(); } @@ -205,6 +209,14 @@ static int showBlacklist(final CommandContext context) { return 0; } + static int setItemOrdering(final CommandContext context) { + final ItemOrdering newOrdering = InventorySorterCommand.Arguments.ORDERING.get(context); + INSTANCE.itemOrdering = newOrdering; + INSTANCE.updateConfig(); + context.getSource().sendSuccess(new TranslatableComponent("inventorysorter.commands.inventorysorter.setorder.ok", newOrdering.toString()), true); + return 0; + } + static Stream listContainers() { return ForgeRegistries.CONTAINERS.getEntries().stream().map(e -> e.getKey().location().toString()); } diff --git a/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java b/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java index bdf481c..555f21d 100644 --- a/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java +++ b/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java @@ -23,6 +23,7 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraftforge.server.command.EnumArgument; public class InventorySorterCommand { public static void register(final CommandDispatcher dispatcher) { @@ -43,7 +44,8 @@ private enum CommandAction { BLADD(InventorySorter::blackListAdd, 1, Arguments.CONTAINER), BLREMOVE(InventorySorter::blackListRemove, 4, Arguments.BLACKLISTED), SHOWLAST(InventorySorter::showLast, 1), - LIST(InventorySorter::showBlacklist, 1); + LIST(InventorySorter::showBlacklist, 1), + SETORDERING(InventorySorter::setItemOrdering, 1, Arguments.ORDERING); private final int permissionLevel; private final ToIntFunction> action; @@ -74,6 +76,7 @@ public LiteralArgumentBuilder getCommand() { public static class Arguments { static final TypedArgumentHandler CONTAINER = new TypedArgumentHandler<>("container", () -> new ContainerClassArgument(InventorySorter::listContainers)); static final TypedArgumentHandler BLACKLISTED = new TypedArgumentHandler<>("blacklisted", () -> new ContainerClassArgument(InventorySorter::listBlacklist)); + static final TypedArgumentHandler ORDERING = new TypedArgumentHandler<>("ordering", ItemOrdering.class, () -> EnumArgument.enumArgument(ItemOrdering.class)); } public static class TypedArgumentHandler { @@ -83,10 +86,12 @@ public static class TypedArgumentHandler { @SuppressWarnings("unchecked") TypedArgumentHandler(final String argName, final Supplier> argumentType) { + this(argName, (Class) TypeResolver.resolveRawArguments(ArgumentType.class, argumentType.get().getClass())[0], argumentType); + } + TypedArgumentHandler(final String argName, Class clazz, final Supplier> argumentType) { this.argName = argName; this.argumentType = argumentType.get(); - final Class[] classes = TypeResolver.resolveRawArguments(ArgumentType.class, this.argumentType.getClass()); - this.clazz = (Class) classes[0]; + this.clazz = clazz; } public static TypedArgumentHandler of(final String argumentName, final Supplier> supplier) { diff --git a/src/main/java/cpw/mods/inventorysorter/ItemOrdering.java b/src/main/java/cpw/mods/inventorysorter/ItemOrdering.java new file mode 100644 index 0000000..79da6cf --- /dev/null +++ b/src/main/java/cpw/mods/inventorysorter/ItemOrdering.java @@ -0,0 +1,65 @@ +/* + * Copyright © 2022 David Koňařík + * This file is part of Inventorysorter. + * + * Inventorysorter is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Inventorysorter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Inventorysorter. If not, see . + */ + +package cpw.mods.inventorysorter; + +import java.util.Comparator; +import java.util.stream.Stream; + +import com.google.common.collect.Multiset; +import com.google.common.collect.Multiset.Entry; + +/** + * Enum deciding how to order items during sorting + */ +public enum ItemOrdering { + BY_COUNT, + BY_MOD_AND_NAME, + BY_NAME; + + public Stream> ordered(Multiset itemCounts) { + if (this == BY_COUNT) + return orderedByCount(itemCounts); + if (this == BY_MOD_AND_NAME) + return orderedByModAndName(itemCounts); + if (this == BY_NAME) + return orderedByName(itemCounts); + throw new IllegalStateException(); + } + + private static Stream> orderedByCount(Multiset itemCounts) { + return itemCounts.entrySet().stream() + .sorted((a, b) -> { + int countComp = Integer.compare(a.getCount(), b.getCount()); + if (countComp != 0) + return -countComp; // Descending + return a.getElement().is.getItem().getRegistryName().toString() + .compareTo(b.getElement().is.getItem().getRegistryName().toString()); + }); + } + + private static Stream> orderedByModAndName(Multiset itemCounts) { + return itemCounts.entrySet().stream() + .sorted(Comparator.comparing(e -> e.getElement().is.getItem().getRegistryName().toString())); + } + + private static Stream> orderedByName(Multiset itemCounts) { + return itemCounts.entrySet().stream() + .sorted(Comparator.comparing(e -> e.getElement().is.getItem().getRegistryName().getPath())); + } +} diff --git a/src/main/java/cpw/mods/inventorysorter/SortingHandler.java b/src/main/java/cpw/mods/inventorysorter/SortingHandler.java index c8c748d..ba83344 100644 --- a/src/main/java/cpw/mods/inventorysorter/SortingHandler.java +++ b/src/main/java/cpw/mods/inventorysorter/SortingHandler.java @@ -20,6 +20,8 @@ import com.google.common.base.*; import com.google.common.collect.*; +import com.google.common.collect.Multiset.Entry; + import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.Slot; @@ -27,6 +29,9 @@ import org.apache.logging.log4j.*; import javax.annotation.*; + +import java.util.Comparator; +import java.util.Iterator; import java.util.function.*; import net.minecraft.world.inventory.CraftingContainer; @@ -123,10 +128,10 @@ private void compactInventory(final ContainerContext context, final Multisetnew String[] {containerTypeName.toString()}); - final UnmodifiableIterator> itemsIterator; + final Iterator> itemsIterator; try { - itemsIterator = Multisets.copyHighestCountFirst(itemcounts).entrySet().iterator(); + itemsIterator = InventorySorter.INSTANCE.itemOrdering.ordered(itemcounts).iterator(); } catch (Exception e) { diff --git a/src/main/resources/assets/inventorysorter/lang/en_us.json b/src/main/resources/assets/inventorysorter/lang/en_us.json index 340f3b8..32c3511 100644 --- a/src/main/resources/assets/inventorysorter/lang/en_us.json +++ b/src/main/resources/assets/inventorysorter/lang/en_us.json @@ -22,6 +22,7 @@ "inventorysorter.commands.inventorysorter.showlast.nosort": "You have not sorted a container yet. Try sorting one!", "inventorysorter.commands.inventorysorter.showblacklist.message": "Current blacklist §e{0}§f", "inventorysorter.commands.inventorysorter.showblacklist.empty": "The blacklist is empty", + "inventorysorter.commands.inventorysorter.setorder.ok": "Set ordering method to §e{0}§f", "inventorysorter.config.containerblacklist": "Container blacklist", "inventorysorter.config.slotblacklist": "Slot type blacklist" -} \ No newline at end of file +} diff --git a/src/main/resources/assets/inventorysorter/lang/en_us.lang b/src/main/resources/assets/inventorysorter/lang/en_us.lang index 536b13f..37ccbd5 100644 --- a/src/main/resources/assets/inventorysorter/lang/en_us.lang +++ b/src/main/resources/assets/inventorysorter/lang/en_us.lang @@ -19,4 +19,5 @@ inventorysorter.commands.inventorysorter.blremove.message=Removed %1$s§f from c inventorysorter.commands.inventorysorter.show.message=Last container sorted %1$s inventorysorter.commands.inventorysorter.list.message=Current blacklist %1$s inventorysorter.commands.inventorysorter.list.empty=The blacklist is empty -inventorysorter.commands.inventorysorter.noop=§cThe last command had no effect (maybe try sorting a container?) \ No newline at end of file +inventorysorter.commands.inventorysorter.noop=§cThe last command had no effect (maybe try sorting a container?) +inventorysorter.commands.inventorysorter.setorder.ok=Set ordering method to §e{0}§f