From 441caa8162bff4f2b73bf25a8a1a23779fc2d957 Mon Sep 17 00:00:00 2001 From: TheSuperGamer20578 <30369708+TheSuperGamer20578@users.noreply.github.com> Date: Sat, 22 Jun 2024 19:49:12 +1000 Subject: [PATCH 1/8] Fixed modded GUIs with non-adjacent slots --- .../inventory_controls/GroupGenerator.java | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index dfca35ff..dad4788f 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -1,6 +1,7 @@ package com.github.khanshoaib3.minecraft_access.features.inventory_controls; import com.github.khanshoaib3.minecraft_access.mixin.*; +import com.google.common.base.CaseFormat; import com.google.common.collect.Lists; import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; import net.minecraft.block.entity.BannerPattern; @@ -27,9 +28,7 @@ import net.minecraft.village.TradeOfferList; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import java.util.*; public class GroupGenerator { @@ -73,7 +72,7 @@ public static List generateGroupsFromSlots(HandledScreenAccessor scr SlotsGroup secondaryBeaconPowersButtonsGroup = new SlotsGroup("secondary_beacon_powers_buttons", null); SlotsGroup lapisLazuliInputGroup = new SlotsGroup("lapis_lazuli_input", null); SlotsGroup enchantsGroup = new SlotsGroup("enchants", null); - SlotsGroup unknownGroup = new SlotsGroup("unknown", null); + List unknownSlots = new ArrayList<>(slots.size()); for (Slot s : slots) { int index = ((SlotAccessor) s).getIndex(); @@ -263,7 +262,7 @@ public static List generateGroupsFromSlots(HandledScreenAccessor scr } // - unknownGroup.slotItems.add(new SlotItem(s)); + unknownSlots.add(new SlotItem(s)); } // @@ -467,8 +466,46 @@ else if (screen.getHandler() instanceof HopperScreenHandler) foundGroups.add(itemOutputGroup); } - if (unknownGroup.slotItems.size() > 0) { - foundGroups.add(unknownGroup); + // Adjacency is used here instead of slot.inventory because some mods have non-adjacent slots in the same + // inventory and adjacent slots in different inventories + List> unknownGroups = new ArrayList<>(unknownSlots.size()); + for (SlotItem slot : unknownSlots) { + unknownGroups.stream() + .filter(group -> + group.stream() + .anyMatch(groupSlot -> + groupSlot.x == slot.x && (groupSlot.y == slot.y + 18 || groupSlot.y == slot.y - 18) + || groupSlot.y == slot.y && (groupSlot.x == slot.x + 18 || groupSlot.x == slot.x - 18) + ) + ) + .findFirst() + .or(() -> { + List group = new ArrayList<>(unknownSlots.size()); + unknownGroups.add(group); + return Optional.of(group); + }) + .get() + .add(slot); + } + Map usedNames = new HashMap<>(unknownGroups.size()); + for (List group : unknownGroups) { + if (group.stream() + .map(slot -> slot.slot.getClass().getSimpleName()) + .distinct() + .limit(2) + .count() == 1) { + String groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.get(0).slot.getClass().getSimpleName()); + if (usedNames.containsKey(groupName)) { + byte n = (byte) (usedNames.get(groupName) + 1); + usedNames.put(groupName, n); + groupName += String.format("_%d", n); + } else { + usedNames.put(groupName, (byte) 1); + } + foundGroups.add(new SlotsGroup(groupName, group)); + } else { + foundGroups.add(new SlotsGroup("unknown_group", group)); + } } // From b297133563b05ab7e24f9eb2175fd5af63af525d Mon Sep 17 00:00:00 2001 From: TheSuperGamer20578 <30369708+TheSuperGamer20578@users.noreply.github.com> Date: Sun, 23 Jun 2024 11:27:40 +1000 Subject: [PATCH 2/8] Don't use vanilla obfuscated class names --- .../inventory_controls/GroupGenerator.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index dad4788f..c51c869d 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -489,23 +489,28 @@ else if (screen.getHandler() instanceof HopperScreenHandler) } Map usedNames = new HashMap<>(unknownGroups.size()); for (List group : unknownGroups) { + String groupName; if (group.stream() .map(slot -> slot.slot.getClass().getSimpleName()) .distinct() .limit(2) .count() == 1) { - String groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.get(0).slot.getClass().getSimpleName()); - if (usedNames.containsKey(groupName)) { - byte n = (byte) (usedNames.get(groupName) + 1); - usedNames.put(groupName, n); - groupName += String.format("_%d", n); - } else { - usedNames.put(groupName, (byte) 1); + groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.get(0).slot.getClass().getSimpleName()); + // Don't use vanilla obfuscated class names + if (groupName.startsWith("class_")) { + groupName = "unknown_group"; } - foundGroups.add(new SlotsGroup(groupName, group)); } else { - foundGroups.add(new SlotsGroup("unknown_group", group)); + groupName = "unknown_group"; } + if (usedNames.containsKey(groupName)) { + byte n = (byte) (usedNames.get(groupName) + 1); + usedNames.put(groupName, n); + groupName += String.format("_%d", n); + } else { + usedNames.put(groupName, (byte) 1); + } + foundGroups.add(new SlotsGroup(groupName, group)); } // From 748731dcb78fb2d5db6646a09cc0df1a7da62689 Mon Sep 17 00:00:00 2001 From: TheSuperGamer20578 <30369708+TheSuperGamer20578@users.noreply.github.com> Date: Sun, 23 Jun 2024 18:00:38 +1000 Subject: [PATCH 3/8] Minor refactoring and reformating --- .../features/inventory_controls/GroupGenerator.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index c51c869d..95dcc8de 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -490,13 +490,14 @@ else if (screen.getHandler() instanceof HopperScreenHandler) Map usedNames = new HashMap<>(unknownGroups.size()); for (List group : unknownGroups) { String groupName; - if (group.stream() - .map(slot -> slot.slot.getClass().getSimpleName()) + boolean isOfSingularSlotType = group.stream() + .map(slot -> slot.slot.getClass()) .distinct() .limit(2) - .count() == 1) { + .count() == 1; + if (isOfSingularSlotType) { groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.get(0).slot.getClass().getSimpleName()); - // Don't use vanilla obfuscated class names + // Don't use vanilla obfuscated class names if (groupName.startsWith("class_")) { groupName = "unknown_group"; } From 2cb8aa345166d0ffb7715c95a17731ff15e30e89 Mon Sep 17 00:00:00 2001 From: boholder Date: Sun, 23 Jun 2024 17:06:12 +0800 Subject: [PATCH 4/8] refactor: extract unknown slots separation logic as method --- .../inventory_controls/GroupGenerator.java | 110 ++++++++++-------- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index 95dcc8de..d6f6ffed 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -466,53 +466,10 @@ else if (screen.getHandler() instanceof HopperScreenHandler) foundGroups.add(itemOutputGroup); } - // Adjacency is used here instead of slot.inventory because some mods have non-adjacent slots in the same - // inventory and adjacent slots in different inventories - List> unknownGroups = new ArrayList<>(unknownSlots.size()); - for (SlotItem slot : unknownSlots) { - unknownGroups.stream() - .filter(group -> - group.stream() - .anyMatch(groupSlot -> - groupSlot.x == slot.x && (groupSlot.y == slot.y + 18 || groupSlot.y == slot.y - 18) - || groupSlot.y == slot.y && (groupSlot.x == slot.x + 18 || groupSlot.x == slot.x - 18) - ) - ) - .findFirst() - .or(() -> { - List group = new ArrayList<>(unknownSlots.size()); - unknownGroups.add(group); - return Optional.of(group); - }) - .get() - .add(slot); - } - Map usedNames = new HashMap<>(unknownGroups.size()); - for (List group : unknownGroups) { - String groupName; - boolean isOfSingularSlotType = group.stream() - .map(slot -> slot.slot.getClass()) - .distinct() - .limit(2) - .count() == 1; - if (isOfSingularSlotType) { - groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.get(0).slot.getClass().getSimpleName()); - // Don't use vanilla obfuscated class names - if (groupName.startsWith("class_")) { - groupName = "unknown_group"; - } - } else { - groupName = "unknown_group"; - } - if (usedNames.containsKey(groupName)) { - byte n = (byte) (usedNames.get(groupName) + 1); - usedNames.put(groupName, n); - groupName += String.format("_%d", n); - } else { - usedNames.put(groupName, (byte) 1); - } - foundGroups.add(new SlotsGroup(groupName, group)); - } + // Unknown slots come from screens in other mods (or unsupported original screens) + // that use original SlotItem class to represent item slots. + // One SlotItem represents one slot. + foundGroups.addAll(separateUnknownSlotsIntoGroups(unknownSlots)); // // Then the non-item-related groups you want to interact with (after you put items into input slots, enchant for example). @@ -565,6 +522,65 @@ else if (screen.getHandler() instanceof HopperScreenHandler) return foundGroups; } + /** + * Separate unknown slots into groups according to their position on the screen. + * Coordinates adjacency is used instead of slot.inventory() to calculate group belonging + * because some mods have: 1. non-adjacent slots in the same inventory 2. adjacent slots in different inventories. + * + * @return Separation result + */ + @NotNull + private static List separateUnknownSlotsIntoGroups(List unknownSlots) { + List groupsOfUnknownSlots = new ArrayList<>(); + List> unknownGroups = new ArrayList<>(unknownSlots.size()); + for (SlotItem slot : unknownSlots) { + unknownGroups.stream() + .filter(group -> + group.stream() + .anyMatch(groupSlot -> + groupSlot.x == slot.x && (groupSlot.y == slot.y + 18 || groupSlot.y == slot.y - 18) + || groupSlot.y == slot.y && (groupSlot.x == slot.x + 18 || groupSlot.x == slot.x - 18) + ) + ) + .findFirst() + .or(() -> { + List group = new ArrayList<>(unknownSlots.size()); + unknownGroups.add(group); + return Optional.of(group); + }) + .get() + .add(slot); + } + Map usedNames = new HashMap<>(unknownGroups.size()); + for (List group : unknownGroups) { + String groupName; + boolean isOfSingularSlotType = group.stream() + .map(slot -> slot.slot.getClass()) + .distinct() + .limit(2) + .count() == 1; + if (isOfSingularSlotType) { + groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.get(0).slot.getClass().getSimpleName()); + // Don't use vanilla obfuscated class names + if (groupName.startsWith("class_")) { + groupName = "unknown_group"; + } + } else { + groupName = "unknown_group"; + } + if (usedNames.containsKey(groupName)) { + byte n = (byte) (usedNames.get(groupName) + 1); + usedNames.put(groupName, n); + groupName += String.format("_%d", n); + } else { + usedNames.put(groupName, (byte) 1); + } + groupsOfUnknownSlots.add(new SlotsGroup(groupName, group)); + } + + return groupsOfUnknownSlots; + } + private static @NotNull List inventoryAndCraftingScreensGroups(@NotNull HandledScreenAccessor screen) { List foundGroups = commonGroups(screen); RecipeBookWidget recipeBookWidget = null; From dd70f1144f3007831b3a9cfde8b5d048eee8ba8e Mon Sep 17 00:00:00 2001 From: boholder Date: Sun, 23 Jun 2024 17:28:47 +0800 Subject: [PATCH 5/8] refactor: slots separating part --- .../inventory_controls/GroupGenerator.java | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index d6f6ffed..49223b3b 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -523,36 +523,37 @@ else if (screen.getHandler() instanceof HopperScreenHandler) } /** - * Separate unknown slots into groups according to their position on the screen. - * Coordinates adjacency is used instead of slot.inventory() to calculate group belonging - * because some mods have: 1. non-adjacent slots in the same inventory 2. adjacent slots in different inventories. + * Separate unknown slots into groups according to their position on the screen, + * and give these group names according to slot instances' classes. * * @return Separation result */ @NotNull - private static List separateUnknownSlotsIntoGroups(List unknownSlots) { - List groupsOfUnknownSlots = new ArrayList<>(); - List> unknownGroups = new ArrayList<>(unknownSlots.size()); - for (SlotItem slot : unknownSlots) { - unknownGroups.stream() - .filter(group -> - group.stream() - .anyMatch(groupSlot -> - groupSlot.x == slot.x && (groupSlot.y == slot.y + 18 || groupSlot.y == slot.y - 18) - || groupSlot.y == slot.y && (groupSlot.x == slot.x + 18 || groupSlot.x == slot.x - 18) - ) - ) + private static List separateUnknownSlotsIntoGroups(List slots) { + // Separate unknown slots into groups. + // Coordinates adjacency is used instead of slot.inventory() to calculate grouping + // because some mods have: 1. non-adjacent slots in the same inventory 2. adjacent slots in different inventories. + List> separatedSlots = new ArrayList<>(slots.size()); + for (SlotItem current : slots) { + // Search for a group which already has one slot that is adjacent to the current slot, + // or create a new group if there is no such group. + Optional> targetGroup = separatedSlots.stream() + .filter(group -> group.stream().anyMatch(groupSlot -> twoSlotsAreAdjacent(current, groupSlot))) .findFirst() .or(() -> { - List group = new ArrayList<>(unknownSlots.size()); - unknownGroups.add(group); + List group = new ArrayList<>(slots.size()); + separatedSlots.add(group); return Optional.of(group); - }) - .get() - .add(slot); + }); + // Add the current slot to this group + targetGroup.ifPresent(group -> group.add(current)); } - Map usedNames = new HashMap<>(unknownGroups.size()); - for (List group : unknownGroups) { + + List result = new ArrayList<>(); + + // Naming groups + Map usedNames = new HashMap<>(separatedSlots.size()); + for (List group : separatedSlots) { String groupName; boolean isOfSingularSlotType = group.stream() .map(slot -> slot.slot.getClass()) @@ -575,10 +576,16 @@ private static List separateUnknownSlotsIntoGroups(List un } else { usedNames.put(groupName, (byte) 1); } - groupsOfUnknownSlots.add(new SlotsGroup(groupName, group)); + result.add(new SlotsGroup(groupName, group)); } - return groupsOfUnknownSlots; + return result; + } + + private static boolean twoSlotsAreAdjacent(SlotItem currSlot, SlotItem groupSlot) { + boolean adjacentOnX = groupSlot.x == currSlot.x && (groupSlot.y == currSlot.y + 18 || groupSlot.y == currSlot.y - 18); + boolean adjacentOnY = groupSlot.y == currSlot.y && (groupSlot.x == currSlot.x + 18 || groupSlot.x == currSlot.x - 18); + return adjacentOnX || adjacentOnY; } private static @NotNull List inventoryAndCraftingScreensGroups(@NotNull HandledScreenAccessor screen) { From 228054e25429d35b98e36038a2e46c40fda50024 Mon Sep 17 00:00:00 2001 From: boholder Date: Sun, 23 Jun 2024 17:46:45 +0800 Subject: [PATCH 6/8] refactor: groups naming part --- .../inventory_controls/GroupGenerator.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index 49223b3b..1ff41614 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -524,7 +524,7 @@ else if (screen.getHandler() instanceof HopperScreenHandler) /** * Separate unknown slots into groups according to their position on the screen, - * and give these group names according to slot instances' classes. + * and give these group names according to slot instances' types (classes). * * @return Separation result */ @@ -552,16 +552,18 @@ private static List separateUnknownSlotsIntoGroups(List sl List result = new ArrayList<>(); // Naming groups - Map usedNames = new HashMap<>(separatedSlots.size()); + Map duplicateCounters = new HashMap<>(separatedSlots.size()); for (List group : separatedSlots) { String groupName; - boolean isOfSingularSlotType = group.stream() + boolean allSlotsHaveSameType = group.stream() .map(slot -> slot.slot.getClass()) .distinct() .limit(2) .count() == 1; - if (isOfSingularSlotType) { - groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.get(0).slot.getClass().getSimpleName()); + if (allSlotsHaveSameType) { + // Set group name to unique slot class name + // e.g. ModAbcSlot -> mod_abc_slot + groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.getFirst().slot.getClass().getSimpleName()); // Don't use vanilla obfuscated class names if (groupName.startsWith("class_")) { groupName = "unknown_group"; @@ -569,13 +571,17 @@ private static List separateUnknownSlotsIntoGroups(List sl } else { groupName = "unknown_group"; } - if (usedNames.containsKey(groupName)) { - byte n = (byte) (usedNames.get(groupName) + 1); - usedNames.put(groupName, n); + + // Already have a group with the same name + if (duplicateCounters.containsKey(groupName)) { + byte n = (byte) (duplicateCounters.get(groupName) + 1); + duplicateCounters.put(groupName, n); + // Add a number suffix groupName += String.format("_%d", n); } else { - usedNames.put(groupName, (byte) 1); + duplicateCounters.put(groupName, (byte) 1); } + result.add(new SlotsGroup(groupName, group)); } From dff57c8be979931668b9628ad4c8a79887988df9 Mon Sep 17 00:00:00 2001 From: TheSuperGamer20578 <30369708+TheSuperGamer20578@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:35:33 +1000 Subject: [PATCH 7/8] Sorted slots to prevent potential bug --- .../features/inventory_controls/GroupGenerator.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index 1ff41614..6634f676 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -530,23 +530,26 @@ else if (screen.getHandler() instanceof HopperScreenHandler) */ @NotNull private static List separateUnknownSlotsIntoGroups(List slots) { + // An unsorted list may result in many groups being created where there should only be one + slots.sort(Comparator.comparing(slot -> ((SlotItem) slot).y).thenComparing(slot -> ((SlotItem) slot).x)); + // Separate unknown slots into groups. - // Coordinates adjacency is used instead of slot.inventory() to calculate grouping + // Coordinates adjacency is used instead of slot.inventory to calculate grouping // because some mods have: 1. non-adjacent slots in the same inventory 2. adjacent slots in different inventories. List> separatedSlots = new ArrayList<>(slots.size()); for (SlotItem current : slots) { // Search for a group which already has one slot that is adjacent to the current slot, // or create a new group if there is no such group. - Optional> targetGroup = separatedSlots.stream() + List targetGroup = separatedSlots.stream() .filter(group -> group.stream().anyMatch(groupSlot -> twoSlotsAreAdjacent(current, groupSlot))) .findFirst() - .or(() -> { + .orElseGet(() -> { List group = new ArrayList<>(slots.size()); separatedSlots.add(group); - return Optional.of(group); + return group; }); // Add the current slot to this group - targetGroup.ifPresent(group -> group.add(current)); + targetGroup.add(current); } List result = new ArrayList<>(); From 41d7a9c1e9ed7cf4bb37fcd53eeecc044d3b3fb5 Mon Sep 17 00:00:00 2001 From: TheSuperGamer20578 <30369708+TheSuperGamer20578@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:21:33 +1000 Subject: [PATCH 8/8] Fixed I18N on unknown groups --- .../inventory_controls/GroupGenerator.java | 24 ++++++++++++------- .../inventory_controls/SlotsGroup.java | 21 +++++++++++++--- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java index 6634f676..156e8c82 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/GroupGenerator.java @@ -27,6 +27,7 @@ import net.minecraft.util.Formatting; import net.minecraft.village.TradeOfferList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -557,7 +558,9 @@ private static List separateUnknownSlotsIntoGroups(List sl // Naming groups Map duplicateCounters = new HashMap<>(separatedSlots.size()); for (List group : separatedSlots) { - String groupName; + String groupKey; + @Nullable String groupName; + @Nullable Byte index; boolean allSlotsHaveSameType = group.stream() .map(slot -> slot.slot.getClass()) .distinct() @@ -567,25 +570,28 @@ private static List separateUnknownSlotsIntoGroups(List sl // Set group name to unique slot class name // e.g. ModAbcSlot -> mod_abc_slot groupName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.getFirst().slot.getClass().getSimpleName()); + groupKey = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, group.getFirst().slot.getClass().getCanonicalName()); // Don't use vanilla obfuscated class names if (groupName.startsWith("class_")) { - groupName = "unknown_group"; + groupKey = "unknown"; + groupName = null; } } else { - groupName = "unknown_group"; + groupKey = "unknown"; + groupName = null; } // Already have a group with the same name - if (duplicateCounters.containsKey(groupName)) { - byte n = (byte) (duplicateCounters.get(groupName) + 1); - duplicateCounters.put(groupName, n); - // Add a number suffix - groupName += String.format("_%d", n); + if (duplicateCounters.containsKey(groupKey)) { + byte n = (byte) (duplicateCounters.get(groupKey) + 1); + duplicateCounters.put(groupKey, n); + index = n; } else { duplicateCounters.put(groupName, (byte) 1); + index = null; } - result.add(new SlotsGroup(groupName, group)); + result.add(new SlotsGroup(groupKey, groupName, index, group)); } return result; diff --git a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/SlotsGroup.java b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/SlotsGroup.java index a3eea523..888481ce 100644 --- a/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/SlotsGroup.java +++ b/common/src/main/java/com/github/khanshoaib3/minecraft_access/features/inventory_controls/SlotsGroup.java @@ -4,6 +4,7 @@ import net.minecraft.client.resource.language.I18n; import net.minecraft.screen.slot.Slot; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; @@ -11,18 +12,30 @@ import java.util.Objects; public class SlotsGroup { - private final String groupName; + private final @NotNull String groupKey; + private final @Nullable String groupName; + private final @Nullable Byte index; public List slotItems; public boolean isScrollable = false; private final HashMap slotNamePrefixMap; - public SlotsGroup(String groupName, List slotItems) { + public SlotsGroup(@NotNull String groupKey, @Nullable String groupName, @Nullable Byte index, @Nullable List slotItems) { this.slotNamePrefixMap = new HashMap<>(); + this.groupKey = groupKey; this.groupName = groupName; + this.index = index; this.slotItems = Objects.requireNonNullElseGet(slotItems, ArrayList::new); } + public SlotsGroup(@NotNull String groupKey, @Nullable List slotItems) { + this(groupKey, null, null, slotItems); + } + + public SlotsGroup(@NotNull String groupKey) { + this(groupKey, null, null, null); + } + public void setSlotPrefix(Slot slot, String prefix) { this.slotNamePrefixMap.put(slot, prefix); } @@ -112,6 +125,8 @@ void setRowColumnPrefixForSlots() { } public String getGroupName() { - return I18n.translate("minecraft_access.slot_group." + this.groupName); + String key = String.format("minecraft_access.slot_group.%s", groupKey); + String translation = groupName == null || I18n.hasTranslation(key) ? I18n.translate(key) : groupName; + return index == null ? translation : String.format("%s %d", translation, index); } }